使用 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);
我有以下助手 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);