1

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

public class XAMLHelper
{
    public IVariableTypeHandler _variableHandler;

    public XAMLHelper()
    {
    }
}

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

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

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

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

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

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

new InjectionProperty()

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

4

1 回答 1

1

一般来说,好的设计建议使助手\操纵器\操作类无状态。在这里,您显然有一个有状态的辅助类,因为您可以通过属性_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; }

然后你可以注册XAMLHelper使用InjectionProperty

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);
于 2019-01-22T21:14:38.950 回答