2012-06-27 184 views
0

我有一种情况,我需要从一个开放的泛型基类中按名称获取具体类。StructureMap open generic

我的类层次结构:

public class Foo { } 

public class Bar { } 

public abstract class OpenGenericBaseClass<T> where T : class { } 

public class ConcreteClass1 : OpenGenericBaseClass<Foo> { } 

public class ConcreteClass2 : OpenGenericBaseClass<Bar> { } 

我的注册代码:

For(typeof(OpenGenericBaseClass<>)).Use(x => x.GetInstance<ConcreteClass1>()); 

For(typeof(OpenGenericBaseClass<>)).Add(x => x.GetInstance<ConcreteClass2>()).Named("Class2"); 

我的程序代码:

ObjectFactory.Configure(
      x => x.Configure(
       a => a.Scan(
        b => 
        { 
         b.AssembliesFromApplicationBaseDirectory(); 
         b.LookForRegistries(); 
        }))); 

     var c1 = ObjectFactory.GetInstance(typeof(OpenGenericBaseClass<>)); 

     var c2 = ObjectFactory.GetNamedInstance(typeof(OpenGenericBaseClass<>), "Class2"); 

到的GetInstance方法(C1)的第一次调用返回的好“ConcreteClass1”对象。 然而对第二个呼叫(对于C2)我得到一个异常: StructureMap异常代码:200找不到名为“等级2”为PluginType TestStructureMapGeneric.OpenGenericBaseClass`1一个实例

我怎样才能让我的C2命名具体实例?

感谢您的帮助。

回答

0

看来StructureMap不支持添加命名配置来打开泛型类型。但是,为什么你需要一个开放的泛型类型?在StructureMap中使用开放泛型类型将泛型参数从一个类传递到另一个类,这就是为什么在不发生异常的情况下不能使用For(typeof(OpenGenericBaseClass<>)).Use(typeof(ConcreteClass1))构造,而必须使用lambda。

public abstract class BaseClass {} 
public abstract class OpenGenericBaseClass<T> : BaseClass where T : class {} 

,并使用下面的注册表代码:

对于这个特殊的例子,我可以通过添加不使用开放式泛型类型基类解决各类

For<BaseClass>().Use<ConcreteClass1>(); 
For<BaseClass>().Add<ConcreteClass2>().Named("Class2"); 

现在,我可以使用此代码轻松解决实例:

var c1 = ObjectFactory.GetInstance<BaseClass>(); // of type ConcreteClass1 
var c2 = ObjectFactory.GetNamedInstance<BaseClass>("Class2"); // of type ConcreteClass2 
+0

嗨@Nekresh,我正在使用开放的泛型基类来p使用虚拟方法来帮助我用不同的对象类型组织工作流。我不能使用简单的基类,因为我失去了共享泛型行为的好处。 – klettier