这是可能的,但如果可以的话,我会寻找替代方案。问题是要使用开放泛型,您必须使用一些反射。这意味着您将受到性能影响。
public class FooRegistry:Registry
{
public FooRegistry()
{
For(typeof(IFoo<>)).Use(x =>
{
var ParamType = x.BuildStack.Current.RequestedType
.GetGenericArguments()[0];
return BuildUsingFooFactory(ParamType);
});
}
private object BuildUsingFooFactory(Type paramType)
{
var factoryType = typeof (FooFactory<>).MakeGenericType(new[] {paramType});
var createMethod = factoryType.GetMethod("Create");
object factory = Activator.CreateInstance(factoryType);
return createMethod.Invoke(factory, new[] {"SomeParameterString"});
}
}
public class FooFactory<T>
{
public IFoo<T> Create(string param)
{
return new Foo<T>();
}
}
public interface IFoo<T>
{
}
public class Foo<T> : IFoo<T>
{
}
您正在按顺序执行以下操作:
- 找出请求的通用参数是什么。(参数类型)
- 为工厂创建非开放的泛型类型(factoryType)
- 抓住它的 create 方法。(创建方法)
- 使用Activator(工厂)创建工厂实例
- 使用您的一些参数调用工厂实例上的 create 方法。
StructureMap 负责将输出转换为正确的接口。
更好的解决方案
不要直接使用 IFoo,而是使用 IFooFactory。这使它更干净,你有一个到 IFooFactory<> 的开放通用映射。然后只需获取生成对象所需的 FooFactory 类型。
public class FooRegistry:Registry
{
public FooRegistry()
{
For(typeof (IFooFactory<>))
.Use(typeof (FooFactory<>))
.CtorDependency<string>("connection")
.Is("SomeConnectionString");
}
}
public interface IFooFactory<T>
{
IFoo<T> CreateInstance();
}
public class FooFactory<T> : IFooFactory<T>
{
public FooFactory(string connection)
{
}
public IFoo<T> CreateInstance()
{
return new Foo<T>();
}
}
public interface IFoo<T>
{
}
public class Foo<T> : IFoo<T>
{
}