使用 IoC 在单例 Class 中不断变化 属性 的最佳设计?

Best Design For Constantly Changing Property Within A Singleton Class With IoC Usage?

我有以下助手 class,它有 public 属性 _variableHandler。 属性 是 public,因为我最初设想在涉及 XAMLHelper class 中的方法之前从调用代码设置 属性,但现在怀疑这是一个聪明的方法。主要是因为我需要经常调用 class 而不是总是更新 _variableHandler 的值,这意味着事情会变得一团糟。

public class XAMLHelper
{
    public IVariableTypeHandler _variableHandler;

    public XAMLHelper()
    {
    }
}

我还有一个工厂,用于提供所需的 VariableTypeHandler 的具体实例。

我还在使用 IoC 容器 (Unity) 来提供 XAMLHelper 的单个实例 class,如下所示。

container.RegisterInstance<XAMLHelper>(new XAMLHelper());

理想情况下,我想保留这个单一实例,但只需在使用以下代码指定时更新 _variableHandler 的值。

container.Resolve(new PropertyInjection(VariableHandlerFactory.GetInstance("Str")));

我试过将片段添加到容器注册中,例如

new InjectionProperty()

但这似乎并没有在第一次实例化后更新 _variableHandler 属性。我在这里错过了一些重要的东西吗?或者尝试做一些 IoC 容器做不到的事情?

通常,好的设计建议使 helper\manipulator\operation classes 无状态。在这里你显然有一个助手 class 它是有状态的,因为你可以通过 属性 _variableHandler 设置对象的状态(不是真实的 属性,它更像是一个字段)。

您可以做的是为 IVariableHandler 创建工厂,在 IoC 中注册它并将其注入 XAMLHelper。然后在调用 helper 时,您只需指定要使用的处理程序并使用工厂重新创建它。工厂可以更聪明地重用已经使用某种缓存创建的对象。

public intefrace IVariableHandlerFactory
{
    IVariableHandler Get(string description);
}

public class VariableHandlerFactory : IVariableHandlerFactory
{
    private readonly IDictionary<string, IVariableHandler> _cache;

    public VariableHandlerFactory()
    {
        _cache = new Dictionary<string, IVariableHandler>();
    }

    public IVariableHandler Get(string description)
    {
        IVariableHandler handler; 

        if(_cache.TryGetValue(description, out handler))
        {
            return handler;         
        }

        handler = //create it...
        _cache[description] = handler;

        return handler;
    }
}

然后在 XAMLHelper

中使用它
public class XAMLHelper
{
    private readonly IVariableHandlerFactory _factory;

    public XAMLHelper(IVariableHandlerFactory factory)
    {
        _factory = factory;
    }

    public void HelpMe(string description)
    {
        var handler = _factory.Get(description);

        //do actual work using handler
    }
}

先把这个放在一边,讨论真正的问题。首先,您缺少 属性:

的注释
[Dependency]
public IVariableTypeHandler VariableHandler { get; set; }

然后您可以使用 InjectionProperty

注册 XAMLHelper
container.RegisterType<VariableTypeHandlerImpl, IVariableTypeHandler>();

using(var lifetime = new ContainerControlledLifetimeManager())
    container.RegisterType<XAMLHelper>(lifetime, new InjectionProperty("VariableHandler");

或者,如果您有 IVariableTypeHandler 的具体实例,您可以使用:

var variableHandler = VariableHandlerFactory.GetInstance("Str");

using(var lifetime = new ContainerControlledLifetimeManager())
    container.RegisterType<XAMLHelper>(lifetime, new InjectionProperty("VariableHandler", variableHandler);