StructureMap和工厂类
本文关键字:工厂 StructureMap | 更新日期: 2023-09-27 17:58:49
我的代码中有一些工厂类,不喜欢对Structermap的调用。我该怎么做才是正确的?
class ManagerBaseFactory
{
public ManagerBase GetInstance(SomeEnum e)
{
Type t;
switch (e)
{
case SomeEnum.A:
t = typeof(Manager1);
case SomeEnum.B:
t = typeof(Manager2);
case SomeEnum.C:
t = typeof(Manager3);
}
return (ManagerBase)StructureMap.ObjectFactory.GetInstance(t);
}
}
我认为以这种方式使用结构映射没有问题。您不喜欢当前解决方案的哪些方面?
您可以使用命名实例,甚至不再需要工厂。结构图链接
public class ServicesRegistry : Registry
{
public ServicesRegistry()
{
For< ManagerBase >().Use< Manager1 >().Named("A");
For< ManagerBase >().Use< Manager2 >().Named("B");
For< ManagerBase >().Use< Manager3 >().Named("C");
}
}
你可以通过调用来检索正确的
SomeEnum e = SomeEnum.A;
ObjectFactory.GetNamedInstance<ManagerBase>(e.ToString());
如果您绝对不希望您的ManagerBaseFactory使用容器,您可以让它访问容器中的所有ManagerBase实现,并让它返回正确的实现。当StructureMap在构造函数中看到某个类型的IEnumerable时,它将注入它所知道的该类型的所有实例。
class ManagerBaseFactory
{
private readonly IEnumerable<ManagerBase> _managers;
public ManagerBaseFactory(IEnumerable<ManagerBase> managers)
{
_managers = managers;
}
public ManagerBase GetInstance(SomeEnum e)
{
Type t;
switch (e)
{
case SomeEnum.A:
t = typeof(Manager1);
break;
case SomeEnum.B:
t = typeof(Manager2);
break;
case SomeEnum.C:
t = typeof(Manager3);
break;
default:
return null;
}
return _managers.FirstOrDefault(m => m.GetType().Equals(t));
}
}
当然,您需要确保所有的ManagerBase实现都加载在容器中:
var container = new Container(x =>
{
x.Scan(scan =>
{
scan.TheCallingAssembly();
scan.AddAllTypesOf<ManagerBase>();
});
});
不清楚您反对哪个部分。您可以做的一个改进是让ManagerBaseFactory
在其构造函数中接受IContainer
,您可以使用它来代替ObjectFactory
静态网关。然后,您可以将ManagerBaseFactory
从容器中拉出,容器将自己注入到工厂中。在没有静态依赖的情况下,工厂将更容易进行单元测试。
您也可以将return语句直接放在switch中,这样您就可以利用泛型:
case SomeEnum.A:
return _container.GetInstance<Manager1>();