Autofac - 通过基类解析泛型

时间:2014-09-10 09:16:16

标签: c# autofac

我有一个接口/类的映射层次结构,它使用由基类约束的泛型,我试图使用基类将它们解析为派生类。我想知道Autofac能否以比我目前更好的方式解决这个问题。

采用以下结构:

public interface IMapper<T1, T2> 
    where T1 : FooBase
    where T2 : BarBase
{
    T1 Map(T2 source);
}


public class FooBarMapper : IMapper<Foo, Bar>
{
    public Foo Map(Bar source)
    {
        return new Foo
        {
            blahblah = source.xyz
        };
    }
}

接下来,我在“Foo”上有一个“To”扩展方法,它引用了基类型,但我想将它解析为正确的类型。我目前这样解决:

public static TDest To<TDest>(this BarBase o) where TDest : FooBase
{
    var genericMapper = typeof(IMapper<,>).MakeGenericType(o.GetType(), typeof(TDest));
    object mapper = IocProxy.Container.Resolve(genericMapper);

    //... etc
}

这解决得很好......但是mapper只是一个对象。所以我必须使用反射来点击“地图”方法。我宁愿避免这样做。 autofac能否以更好的方式做到这一点,以便我最终得到一个IMapper而不是一个对象?例如,我更喜欢这样做,但autofac显然无法解决它:

var mapper = IocProxy.Container.Resolve<IMapper<FooBase, TDest>>();

1 个答案:

答案 0 :(得分:0)

这个问题的答案有点难看。因为你无法创造&#34; To&#34;使用1泛型的扩展方法,你必须使代码看起来很丑,以便它可以推断出两种类型。像这样:

public static TDest To<TDest,TSource>(this TSource o) where TDest : new()
{
    var mapper = IocProxy.Container.Resolve<IMapper<TSource, TDest>>();
    return mapper.Map(o);
}

在更深处,我们得到了这个丑陋的电话:

var b = a.To<Bar,Foo>(); //<-- to convert it to "Bar" we need to specify both generics

是的,丑陋的!谁真的知道什么被映射到这里!除非你明确指明类型,否则你知道有些人现在已经走了多么疯狂。

无论如何,因为我不喜欢这样,我开发了一种解决方法来提高可读性。首先,我创建了一个Map类来包装我的对象(以及我的&#34; To&#34;函数)。这是一个额外的步骤,但作为一个很好的中介,帮助autofac正确解决泛型:

public class Map<TSource> where TSource : new()
{
    public TSource Object { get; set; }
    public Map(TSource o)
    {
        Object = o;
    }

    public TDest To<TDest>()
    {
        var mapper = IocProxy.Container.Resolve<IMapper<TSource, TDest>>();
        return mapper.Map(Object);
    }
}

然后使用稍微不同的通用扩展方法来获取Mapper(并将代码转换为我想要的样式):

public static Map<TDest> Map<TDest>(this TDest o) where TDest : new()
{
    return new Map<TDest>(o);
}

这确实稍微改变了我想要的方式,但它同样也是如此。

所以不是这样:

foo.To<Bar, Foo>();

代码看起来像这样

foo.Map().To<Bar>()

你甚至可以进一步扩展它并添加和接口到Map类并让Autofac解决它,但我想这取决于你是如何自动编写映射器的。最后,性能提升可能微不足道。