用StructureMap注册通用工厂的方法
我试图在我的structuremap注册表中的generics工厂类上使用方法。 通常,我会在使用工厂方法注册类型时使用以下内容:
For().Use(x => new FooFactory().GetFoo());
注册generics类型时如下:
For(typeof(ISomeGeneric)).Use(typeof(SomeGeneric));
如何将两者结合起来并从通用工厂方法中检索generics类型? 我认为应该是这样的:
For(typeof(IFoo)).Use(typeof(x => new FooFactory().Create(someParameter));
这只是给了一个
"Cannot convert lambda expression to type object because it is not a delegate type"
错误。 我尝试了各种组合,但我很难过。 有任何想法吗?
谢谢。
这是可能的,但如果可以,我会寻找替代方案。 问题是,要使用开放式generics,您必须使用一些reflection。 这意味着您将受到性能影响。
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 { public IFoo Create(string param) { return new Foo (); } } public interface IFoo { } public class Foo : IFoo { }
你按顺序做的是以下几点:
- 找出所请求的generics参数是什么。 (ParamType)
- 为工厂创建非开放generics类型(factoryType)
- 从中获取create方法。 (createMethod)
- 使用Activator(工厂)创建工厂实例
- 使用some参数调用工厂实例上的create方法。
StructureMap负责将输出转换为正确的接口。
改善方案
而不是直接使用IFoo,使用IFooFactory。 这使得它更清晰,你有一个开放的通用映射到IFooFactory <>。 然后只需获取生成对象所需的FooFactory类型。
public class FooRegistry:Registry { public FooRegistry() { For(typeof (IFooFactory<>)) .Use(typeof (FooFactory<>)) .CtorDependency("connection") .Is("SomeConnectionString"); } } public interface IFooFactory { IFoo CreateInstance(); } public class FooFactory : IFooFactory { public FooFactory(string connection) { } public IFoo CreateInstance() { return new Foo (); } } public interface IFoo { } public class Foo : IFoo { }