我假设您没有在测试中使用 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 命名实现并解析了 ILoggers 列表。然后为记录器清除策略并进行检查以确保无法解析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[]>());
注意事项和警告
- 不要在生产代码中使用它——我只会将它用于测试目的
- 这可能无法捕获所有适用的策略,并且不完整或不适用于所有边缘情况(例如拦截或其他深奥的场景)