StructureMap和工厂类

时间:2011-06-10 20:58:33

标签: c# structuremap

我的代码中有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);
    }
}

3 个答案:

答案 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>();