C# 如何从Unity映射中删除(注销)已注册实例?
我遇到了一个我现在无法解决的问题。 我有以下资料:C# 如何从Unity映射中删除(注销)已注册实例?,c#,unity-container,ioc-container,instance,registering,C#,Unity Container,Ioc Container,Instance,Registering,我遇到了一个我现在无法解决的问题。 我有以下资料: UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance); 其中,UnityHelper.DefaultContainer是获取加载配置的unity容器的助手 在这里,我注册了instance作为IMyInterface的一个实例 因此,我想在任何地方(使用后的某个时间)删除此映射。把它拿开。我怎么能做到 我试过: UnityHe
UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance);
其中,UnityHelper.DefaultContainer
是获取加载配置的unity容器的助手
在这里,我注册了instance
作为IMyInterface
的一个实例
因此,我想在任何地方(使用后的某个时间)删除此映射。把它拿开。我怎么能做到
我试过:
UnityHelper.DefaultContainer.Teardown(instance)
但是不成功,以下代码仍返回实例
:
UnityHelper.DefaultContainer.ResolveAll<IMyInterface>()
UnityHelper.DefaultContainer.ResolveAll()
我想这就是你要找的
var lifetimeManager = new TransientLifetimeManager();
UnityHelper.DefaultContainer.RegisterInstance(typeof(IMyInterface), "test", instance, lifetimeManager);
lifetimeManager.RemoveValue();
我有一个类似的要求,我想在unity容器中临时存储对象,但发现这是不可能的(或者至少很容易做到)。 如果您的目标是为unity提供一个方便使用的临时存储位置,那么请创建一个临时存储服务
public class TemporaryStorageService : ITemporaryStorageService
{
public void Deposit<T>(Object o, string key)
{
System.Windows.Application.Current.Properties[key] = o;
}
public T Withdraw<T>(string key)
{ T o = (T)System.Windows.Application.Current.Properties[key];
System.Windows.Application.Current.Properties.Remove(key);
return o;
}
}
public类临时存储服务:ITemporaryStorageService
{
公共作废存款(对象o,字符串键)
{
System.Windows.Application.Current.Properties[key]=o;
}
公共T撤消(字符串键)
{to=(T)System.Windows.Application.Current.Properties[key];
System.Windows.Application.Current.Properties.Remove(键);
返回o;
}
}
向Unity注册您的服务。然后,当您希望存储对象时,调用存款方法;当您希望删除对象时,调用取款方法。
更全面的解释可以是以下是我如何处理unity容器中的注销实例 我需要实现如下添加/删除功能:
public interface IObjectBuilder
{
void AddInstance<T>(T instance);
void RemoveInstance<T>(T instance);
}
以下是最终实施:
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);
}
字典实例=新字典();
公共void附加实例(T实例)
{
ExplicitLifetimeManager e=新的ExplicitLifetimeManager();
实例[实例]=e;
Container.RegisterInstance(实例e);
}
公共无效抗议(T实例)
{
实例[instance].RemoveValue();
实例。删除(实例);
}
在自定义生存期管理器上调用removevalue会导致实例被注销我也遇到了同样的问题,在试验之后,我使用标准ContainerControlled LifetimeManager解决了这个问题,并在我想要删除容器实例时调用removevalue。请注意,如果您不使用接口,并且您的对象具有容器可以找到并使用的构造函数,则在您使用lifetimeManager.RemoveValue()销毁实例后,它将重新创建实例
[TestClass]
公共类UnityContainerTest
{
[测试方法]
public void RemoveFromContainer()
{
UnityContainer容器=新的UnityContainer();
MyUnityMember成员=新的MyUnityMember(5);
LifetimeManager LifetimeManager=新的ContainerControlled LifetimeManager();
容器注册状态(成员,终身管理者);
var resolved=container.Resolve();
Assert.IsNotNull(已解析);
lifetimeManager.RemoveValue();
尝试
{
resolved=container.Resolve();
Assert.Fail(已解析+“仍在容器中”);
}
捕获(解决失败异常)
{
}
}
公共类MyUnityMember
{
公共MyUnityMember(int x)
{
I=x;
}
公共整数I{get;私有集;}
}
}
我也遇到了同样的问题,刚刚从我的容器中删除了ContainerControlled LifetimeManager
的注册:
foreach (var registration in container.Registrations
.Where(p => p.RegisteredType == typeof(object)
&& p.Name == name
&& p.LifetimeManager.Type == typeof(ContainerControlledLifetimeManager)))
{
registration.LifetimeManager.RemoveValue();
}
这是一个老问题,但有些答案是误导性的,所以我将提供我自己的答案。
你不能团结一致。故事结束了。
对注册生存期管理器调用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();
}
}
公共接口SomeInterface
{
int Foo{get;set;}
}
公共类SomeImplementation:SomeInterface
{
公共int Foo{get;set;}
}
静态void Main(字符串[]参数)
{
UnityContainer iocContainer=新的UnityContainer();
字符串registerName=“实例”;
//注册前
解析(iocContainer、registerName);
RegisterInstance(registerName,newsomeImplementation());
//注册后
解析(iocContainer、registerName);
ClearValue(iocContainer、registerName);
//后清除值
解析(iocContainer、registerName);
}
私有静态无效解析(UnityContainer iocContainer,字符串名称)
{
if(iocContainer.IsRegistered(名称))
iocContainer.Resolve(名称);
iocContainer.ResolveAll();
}
私有静态void ClearValue(UnityContainer iocContainer,字符串名称)
{
foreach(iocContainer.Registrations.Where中的var注册(p=>p.RegisteredType==typeof(T)
&&p.Name==名称)
{
registration.LifetimeManager.RemoveValue();
}
}
如果您调试它,您将看到在调用ClearValue
之后,容器仍然表示它已注册,但是如果您尝试解析该实例,它将抛出异常。更糟糕的是,调用ResolveAll
也会失败
总之,无论您是使用另一个IoC或自定义类来包装您的注册实例,还是提供您自己的LifeTimeManager,ResolveAll
和IsRegistered
都不会像预期的那样运行,并且注册仍然存在。所以不要尝试,因为
foreach (var registration in container.Registrations
.Where(p => p.RegisteredType == typeof(object)
&& p.Name == name
&& p.LifetimeManager.Type == typeof(ContainerControlledLifetimeManager)))
{
registration.LifetimeManager.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();
}
}