统一注销服务 [英] Unregister service from unity

查看:82
本文介绍了统一注销服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中使用Unity.对于一项集成测试,我们想要更改向应用程序注册的一项服务(因为它需要一些硬件).

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.

知道我该怎么做吗?

推荐答案

我假设您没有在测试中使用Container.IsRegistered(这并不总是一个有效的假设).

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

与@Tipx答案类似的方法是重新注册,但提供一个 InjectionMember ,它将清除与该类型关联的所有策略.这样做的好处是,由于已删除策略配置,因此Unity应该像从未注册过的类型一样工作(即使它们将出现在注册"列表中).

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).

这是 InjectionMember ClearAllPolicies,它清除策略:

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);
    }
}

这是一个示例,其中注册了3个以 ILogger 命名的实现,并解析了 ILogger 的列表.然后清除记录器的策略,并进行检查以确保无法解析 ILogger :

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[]>());

注意事项警告

  • 请勿在生产代码中使用它-我只会将其用于测试目的
  • 这可能无法捕获所有适用的策略,并且可能不完整或不适用于每种极端情况(例如拦截或其他深奥的场景)
  • 这篇关于统一注销服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆