繁体   English   中英

用StructureMap注册通用工厂的方法

[英]Registering Method on Generic Factory with StructureMap

我试图在我的structuremap注册表中的泛型工厂类上使用方法。 通常,我会在使用工厂方法注册类型时使用以下内容:

For<Foo>().Use(x => new FooFactory().GetFoo());

注册泛型类型时如下:

For(typeof(ISomeGeneric<>)).Use(typeof(SomeGeneric<>));

如何将两者结合起来并从通用工厂方法中检索泛型类型? 我认为应该是这样的:

For(typeof(IFoo<>)).Use(typeof(x => new FooFactory<>().Create(someParameter));

这只是给了一个

"Cannot convert lambda expression to type object because it is not a delegate type" 

错误。 我尝试了各种组合,但我很难过。 有任何想法吗?

谢谢。

这是可能的,但如果可以,我会寻找替代方案。 问题是,要使用开放式泛型,您必须使用一些反射。 这意味着您将受到性能影响。

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>
{   
}

你按顺序做的是以下几点:

  1. 找出所请求的泛型参数是什么。 (ParamType)
  2. 为工厂创建非开放泛型类型(factoryType)
  3. 从中获取create方法。 (createMethod)
  4. 使用Activator(工厂)创建工厂实例
  5. 使用some参数在工厂实例上调用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>
{   
}

暂无
暂无

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

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