我的代码中有som工厂类,不喜欢调用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);
}
}
答案 0 :(得分:2)
我没有看到以这种方式使用结构图的问题。你对目前的解决方案不喜欢什么?
您可以使用您甚至不再需要工厂的命名实例。 structuremap link
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());
答案 1 :(得分:2)
如果您绝对不希望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>();
});
});
答案 2 :(得分:0)
目前尚不清楚你反对的部分。您可以做的一项改进是让ManagerBaseFactory
在其构造函数中加入IContainer
,您可以使用它来代替ObjectFactory
静态网关。然后,您可以将ManagerBaseFactory
拉出容器,容器将自己注入工厂。在没有静态依赖性的情况下,工厂将更容易进行单元测试。
您也可以将return语句直接放在开关中,这样您就可以利用泛型:
case SomeEnum.A:
return _container.GetInstance<Manager1>();