取消注册统一服务

时间:2017-05-12 09:10:02

标签: c# .net dependency-injection unity-container

我在我的应用程序中使用Unity。对于一个集成测试,我们希望更改注册到应用程序的服务之一(因为它需要一些硬件)。

所以,我能够注册新的" mock"输入,但我无法删除为此接口注册的其他实现。

另外,目前我们注册了一个"列表"这个界面(它是某种驱动程序),我们想删除所有其他实例。

知道我怎么能这样做吗?

2 个答案:

答案 0 :(得分:0)

您可以使用模拟或空白实现覆盖注册。在命名注册的情况下,只要您使用相同的名称注册,它就会起作用。当您添加新注册时,Unity将忽略之前的注册。

在我们的UnitTesting项目中,我们目前添加所有常规注册,然后在设置中我们在它们上面注册模拟。

答案 1 :(得分:0)

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

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

这里是清除政策的InjectionMember ClearAllPolicies:

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无法解决:

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

警告&amp;警告

  • 不要在生产代码中使用它 - 我只会将其用于测试目的
  • 这可能不会捕获所有适用的政策,并且不完整或不适用于每个边缘情况(例如拦截或其他深奥情景)