这是一个老问题,但有些答案具有误导性,因此我将提供自己的答案。Unity 无法做到这一点。故事的结局。调用RemoveValue
注册生命周期管理器不会实现注销(有关生命周期管理器的更多信息),并且该方法不打算注销任何东西。所以最终的行为是出乎意料的,也不方便。当然,RemoveValue
如果您注册实现或工厂方法,则更没有意义,尽管问题是关于取消注册实例。考虑下一段代码
public interface SomeInterface
{
int Foo { get; set; }
}
public class SomeImplementation: SomeInterface
{
public int Foo { get; set; }
}
static void Main(string[] args)
{
UnityContainer iocContainer = new UnityContainer();
string registerName = "instance";
//before any registration
Resolve<SomeInterface>(iocContainer, registerName);
iocContainer.RegisterInstance<SomeInterface>(registerName, new SomeImplementation());
//after registration
Resolve<SomeInterface>(iocContainer, registerName);
ClearValue<SomeInterface>(iocContainer, registerName);
//after clear value
Resolve<SomeInterface>(iocContainer, registerName);
}
private static void Resolve<T>(UnityContainer iocContainer,string name)
{
if (iocContainer.IsRegistered<T>(name))
iocContainer.Resolve<T>(name);
iocContainer.ResolveAll<T>();
}
private static void ClearValue<T>(UnityContainer iocContainer, string name)
{
foreach (var registration in iocContainer.Registrations.Where(p => p.RegisteredType == typeof(T)
&& p.Name==name))
{
registration.LifetimeManager.RemoveValue();
}
}
如果你调试它,你会看到在调用 之后ClearValue
,容器仍然说它已注册,但如果你尝试解析该实例,它会抛出异常。更糟糕的是,调用ResolveAll<T>
也会失败。
总而言之,无论您是否这样做ClearValue
,用另一个 IoC 或自定义类包裹您的注册实例,或者提供您自己的 LifeTimeManager,ResolveAll<T>
并且IsRegistered<T>
不会按预期运行,并且注册仍然存在。所以不要尝试它,因为它不起作用,并且会在未来引起问题。