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();
        }
    }