简体   繁体   English

StructureMap 和工厂类

[英]StructureMap and factory classes

I have som factory classes in my code and do not like the call to Structermap.我的代码中有一些工厂类,不喜欢对 Structermap 的调用。 How should i do this the right way?我应该如何以正确的方式做到这一点?

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);
    }
}

I don't see the problem in using structure map this way.我没有看到以这种方式使用结构 map 的问题。 What do you not like about the current solution?您不喜欢当前解决方案的哪些方面?

You could use named instances that you will not even need the factory anymore.您可以使用您甚至不再需要工厂的命名实例。 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");
    }
}

You can than retrieve the correct one by just calling您可以通过调用来检索正确的

SomeEnum e = SomeEnum.A;
ObjectFactory.GetNamedInstance<ManagerBase>(e.ToString());

If you absolutely do not want your ManagerBaseFactory to use the container, you could give it access to all of the ManagerBase implementations from the container, and have it return the correct one.如果你绝对不希望你的 ManagerBaseFactory 使用容器,你可以让它访问容器中的所有 ManagerBase 实现,并让它返回正确的实现。 When StructureMap sees an IEnumerable of a type in a constructor, it will inject all instances of that type that it knows about.当 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));
    }
}

And of course you need to make sure all of your ManagerBase implementations are loaded in the container:当然,您需要确保所有 ManagerBase 实现都加载到容器中:

var container = new Container(x =>
{
    x.Scan(scan =>
    {
        scan.TheCallingAssembly();
        scan.AddAllTypesOf<ManagerBase>();
    });
});

It isn't clear what part you object to.目前尚不清楚您 object 属于哪个部分。 One improvement you could make is to have ManagerBaseFactory take in an IContainer in its constructor, which you can use in place of the ObjectFactory static gateway.您可以进行的一项改进是让ManagerBaseFactory在其构造函数中接收一个IContainer ,您可以使用它来代替ObjectFactory static 网关。 Then you can pull ManagerBaseFactory out of the container, and the container will inject itself into the factory.然后你可以把ManagerBaseFactory从容器中拉出来,容器就会将自己注入到工厂中。 The factory will be easier to unit test without the static dependency.如果没有 static 依赖项,工厂将更容易进行单元测试。

You could also put the return statements directly in the switch so you can take advantage of generics:您也可以将 return 语句直接放在 switch 中,这样您就可以利用 generics:

case SomeEnum.A:
  return _container.GetInstance<Manager1>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM