bug*_*g0r 34 c# instance ioc-container unity-container registering
我遇到了一个我现在无法解决的问题.我有以下内容:
UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance);
Run Code Online (Sandbox Code Playgroud)
UnityHelper.DefaultContainer我的助手在哪里获得带有加载配置的统一容器.
在这里我注册instance为一个实例IMyInterface.
所以在任何地方(使用后一段时间)我想删除此映射.完全删除它.我怎么能这样做?
我试过了:
UnityHelper.DefaultContainer.Teardown(instance)
Run Code Online (Sandbox Code Playgroud)
但是不成功,以下代码仍会返回instance:
UnityHelper.DefaultContainer.ResolveAll<IMyInterface>()
Run Code Online (Sandbox Code Playgroud)
Joh*_*zek 28
我有同样的问题,只是删除了ContainerControlledLifetimeManager我的注册Container:
foreach (var registration in container.Registrations
.Where(p => p.RegisteredType == typeof(object)
&& p.Name == name
&& p.LifetimeManager.Type == typeof(ContainerControlledLifetimeManager)))
{
registration.LifetimeManager.RemoveValue();
}
Run Code Online (Sandbox Code Playgroud)
er-*_*r-v 11
我认为这就是你要找的东西.
var lifetimeManager = new TransientLifetimeManager();
UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance, lifetimeManager);
lifetimeManager.RemoveValue();
Run Code Online (Sandbox Code Playgroud)
以下是我从统一容器处理取消注册实例的方法
我需要实现这样的添加/删除功能:
public interface IObjectBuilder
{
void AddInstance<T>(T instance);
void RemoveInstance<T>(T instance);
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个自定义生命周期管理器来执行
public class ExplicitLifetimeManager :
LifetimeManager
{
object Value;
public override object GetValue()
{
return Value;
}
public override void SetValue(object newValue)
{
Value = newValue;
}
public override void RemoveValue()
{
Value = null;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是最终实施:
Dictionary<object, ExplicitLifetimeManager> Instances = new Dictionary<object, ExplicitLifetimeManager>();
public void AddInstance<T>(T instance)
{
ExplicitLifetimeManager e = new ExplicitLifetimeManager();
Instances[instance] = e;
Container.RegisterInstance(instance, e);
}
public void RemoveInstance<T>(T instance)
{
Instances[instance].RemoveValue();
Instances.Remove(instance);
}
Run Code Online (Sandbox Code Playgroud)
在自定义生存期管理器上调用removevalue会导致实例未注册
这是一个老问题,但有些答案会产生误导,所以我会提供自己的答案.你不能用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();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您调试它,您将看到在调用之后ClearValue,容器仍然表示它已注册,但如果您尝试解析该实例,则会抛出异常.更糟糕的是,呼叫ResolveAll<T>也会失败.
总结一下,无论你是做什么ClearValue,用另一个IoC或自定义类包装你的寄存器实例,或提供你自己的LifeTimeManager,ResolveAll<T>并且IsRegistered<T>不会按预期运行,并且注册仍然存在.因此,不要尝试它,因为它不会工作,它将导致问题.