2017-07-21 72 views
1

我試圖建立本地化本文檔以下IStringLocalizer與第三方DI

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization

我認爲如果你使用內置的DI,它就可以工作但我使用的是簡單的噴油器,而不是建立在DI中,所以它抱怨我沒有註冊IStringLocalizer。我怎麼去註冊IStringLocalizer,因爲我顯然無法做到這一點

container.Register<IStringLocalizer, StringLocalizer>(Lifestyle.Scoped); 

感謝

回答

2

要獲得本地化的ASP.NET核心工作,你將不得不調用從AddLocalization()ConfigureServices方法中:

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add localization 
    services.AddLocalization(); 

    // Normal MVC stuff 
    services.AddMvc(); 

    // Simple Injector integration 
    IntegrationSimpleInjector(services); 
} 

private void IntegrationSimpleInjector(IServiceCollection services) 
{ 
    container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle(); 

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 

    services.AddSingleton<IControllerActivator>(
     new SimpleInjectorControllerActivator(container)); 

    services.EnableSimpleInjectorCrossWiring(container); 
    services.UseSimpleInjectorAspNetRequestScoping(container); 
} 

但是,這隻允許IStringLocalizer<T>從ASP.NET Core配置系統解析,而不是從Simple Injector解析。爲了達到此目的,您必須將IStringLocalizer<T>交叉連接到Simple Injector容器。這通常意味着調用container.CrossWire<T>(app),但由於IStringLocalizer<T>是通用的,因此您必須定義一個代理類,以將調用轉發給從Core配置系統解析出的類型。這種類型可能如下:

class StringLocalizerProxy<T> : IStringLocalizer<T> 
{ 
    private readonly IServiceScope scope; 
    public StringLocalizerProxy(IServiceScope scope) => this.scope = scope; 
    public LocalizedString this[string name] => Instance[name]; 
    public LocalizedString this[string name, params object[] a] => Instance[name, a]; 
    public IEnumerable<LocalizedString> GetAllStrings(bool c) => Instance.GetAllStrings(c); 
    public IStringLocalizer WithCulture(CultureInfo c) => Instance.WithCulture(c); 
    private IStringLocalizer<T> Instance => 
     scope.ServiceProvider.GetRequiredService<IStringLocalizer<T>>(); 
} 

可以按如下這個代理添加到簡單的注射器:

var scopeFactory = builder.ApplicationServices.GetRequiredService<IServiceScopeFactory>(); 

container.Register<IServiceScope>(scopeFactory.CreateScope, Lifestyle.Scoped); 

container.Register(typeof(IStringLocalizer<>), typeof(StringLocalizerProxy<>), 
    Lifestyle.Scoped); 

有了這個代理和之前的註冊,你將能夠注入IStringLocalizer<T>實例到您的應用組件。例如:

public class HomeController : Controller 
{ 
    private readonly IStringLocalizer<HomeController> localizer; 

    public HomeController(IStringLocalizer<HomeController> localizer) 
    { 
     this.localizer = localizer; 
    } 
} 
+0

謝謝@Steven,這一切都有道理但是我得到以下有關IServiceScope未被註冊的錯誤? ActivationException:類型StringLocalizerProxy 的構造函數包含名稱爲'scope'且類型爲IServiceScope的參數未註冊。請確保已註冊IServiceScope,或更改StringLocalizerProxy 的構造函數。 –

+0

你打電話給'EnableSimpleInjectorCrossWiring'嗎? – Steven

+0

是的,我做過了 - 是否有可能使用IMapper自動映射器導致問題。我從來沒有使用過EnableSimpleInjectorCrossWiring並使用IMapper,然後不得不更新簡單的注入器來獲取EnableSimpleInjectorCrossWiring –