unitycontainer / microsoft-dependency-injection

Unity.Microsoft.DependencyInjection package
Apache License 2.0
63 stars 36 forks source link

How to register Microsoft.Extensions.Localization in Unity #35

Closed OculiViridi closed 5 years ago

OculiViridi commented 5 years ago

I'm moving from default .NET Core DI Container to Unity DI Container for memory leaks issues. I've almost everything in place now, except for one thing, the Localization. I'm using the Microsoft.Extensions.Localization package and I need to register it on Unity.

When using it with the default DI Container, there is the extension method by Microsoft and the registration is done like this:

services.AddLocalization(options => options.ResourcesPath = "Resources");

Then there is some configuration:

services.Configure<RequestLocalizationOptions>(options =>
{
    options.DefaultRequestCulture = new RequestCulture("en-US");
    // Formatting numbers, dates, etc.
    options.SupportedCultures = _supportedCultures;
    // Localized UI strings
    options.SupportedUICultures = _supportedCultures;
});

Is there something similar for Unity or do I need to write a custom registration method? Does anybody already used Microsoft.Extensions.Localization library with Unity before?

ENikS commented 5 years ago

Supposedly it should be added to services the same way you would with built-in DI. Anything added to Service Collection should be registered with Unity automatically.

OculiViridi commented 5 years ago

Yes... but what I was missing is the registration on Unity. So I finally wrote this code:

public static class UnityConfiguration
{
    // Here there are some more methods for configuration of other dependencies like:
    // MediatR, DbContext, AutoMapper, etc....

    public static void ConfigureLocalization(this IUnityContainer container)
    {
        var options = Options.Create(new LocalizationOptions { ResourcesPath = "Resources" });
        ILoggerFactory logger = NullLoggerFactory.Instance;

        container.RegisterType<IStringLocalizerFactory, ResourceManagerStringLocalizerFactory>(new ContainerControlledLifetimeManager(), new InjectionConstructor(options, logger));
        container.RegisterType(typeof(IStringLocalizer<>), typeof(StringLocalizer<>));
    }
}

UnityContainer container = new UnityContainer();

container.RegisterMediator(new TransientLifetimeManager());
container.RegisterMediatorHandlers(typeof(MachineCreateCommandHandler).GetTypeInfo().Assembly);
container.ConfigureDbContext(configuration);
container.ConfigureAutoMapper();

// and...
container.ConfigureLocalization(); 

It seems to work, so is it good?

ENikS commented 5 years ago

If it works, it should be good. You do not need to pass TransientManager, It will be implicitly added by Unity.

ENikS commented 5 years ago

If nothing else, I am closing it. Feel free to reopen if more issues show up.