Unregister service from unity

六眼飞鱼酱① 提交于 2019-12-12 06:17:28

问题


I'm using Unity within my application. For one integration test, we want to change one of the service registered to the application(because it would require some hardware).

So, I'm able to Register the new "mock" type, but I'm unable to remove the other implementation registered for this interface.

Also to mention, currently we register a "list" of this interface(it's some kind of driver) and we would like to remove all the others instance.

Any idea how I could do this?


回答1:


You can simply override the registration with either mocks, or a blank implementation. In the case of named registrations, it will work as long as you register with the same name. As you add a new registration, Unity will ignore the former registrations.

In our UnitTesting projects, we currently add all the regular registrations, then in the setup we register mocks on top of them.




回答2:


I'm assuming you are not using Container.IsRegistered in your tests (which is not always a valid assumption).

A similar approach to @Tipx answer is to re-register but provide an InjectionMember that will clear all of the policies associated with the type. This has the benefit that, since the policy configuration has been removed, Unity should work as if the types were never registered (even though they will appear in the Registrations list).

Here's the InjectionMember ClearAllPolicies which clears the policies:

public class ClearAllPolicies : InjectionMember
{
    public override void AddPolicies(Type serviceType, Type implementationType, string name, IPolicyList policies)
    {
        var serviceTypeBuildKey = new NamedTypeBuildKey(serviceType, name);
        policies.Clear<IBuildKeyMappingPolicy>(serviceTypeBuildKey);

        var buildKey = new NamedTypeBuildKey(implementationType, name);

        policies.Clear<IBuildKeyMappingPolicy>(buildKey);
        policies.Clear<IConstructorSelectorPolicy>(buildKey);
        policies.Clear<IBuildPlanCreatorPolicy>(buildKey);
        policies.Clear<IBuildPlanPolicy>(buildKey);
        policies.Clear<IMethodSelectorPolicy>(buildKey);
        policies.Clear<IPropertySelectorPolicy>(buildKey);
        policies.Clear<ILifetimeFactoryPolicy>(buildKey);
        policies.Clear<ILifetimePolicy>(buildKey);
        policies.Clear<IBuilderPolicy>(buildKey);

        DependencyResolverTrackerPolicy.RemoveResolvers(policies, buildKey);
    }
}

Here's an example where 3 ILogger named implementations are registered and a list of ILoggers is resolved. Then the polices are cleared for the loggers and a check is done to ensure that ILogger can't be resolved:

IUnityContainer container = new UnityContainer();

container.RegisterType<ILogger, MyLogger>("Logger1");
container.RegisterType<ILogger, MyLogger>("Logger2");
container.RegisterType<ILogger, MyLogger>("Logger3");

// Resolve list of all loggers
var loggers = container.Resolve<ILogger[]>();

// Remove Policies for all ILoggers using ClearAllPolicies
foreach (var registration in container.Registrations
                                      .Where(r => r.RegisteredType == typeof(ILogger)))
{
    container.RegisterType(
       registration.RegisteredType,
       registration.MappedToType, 
       registration.Name, 
       new ClearAllPolicies());
}

// Ensure that when we try to resolve an ILogger or list of ILogger's that
// an exception is thrown
Assert.Throws<ResolutionFailedException>(() => container.Resolve<ILogger>("Logger1"));
Assert.Throws<ResolutionFailedException>(() => container.Resolve<ILogger>("Logger2"));
Assert.Throws<ResolutionFailedException>(() => container.Resolve<ILogger>("Logger3"));
Assert.Throws<ResolutionFailedException>(() => container.Resolve<ILogger[]>());

Caveats & Warnings

  • Do not use this in production code -- I would only use this for testing purposes
  • It's possible that this does not capture all of the applicable policies and is not complete or does not work for every edge case (e.g. Interception or other esoteric scenarios)


来源:https://stackoverflow.com/questions/43933761/unregister-service-from-unity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!