StructureMap 2.6.1,一个IRepository <t>和一个EFRepository <t,tcontext> </t,tcontext> </t>

时间:2011-05-09 23:00:55

标签: generics structuremap

所以我觉得我会很光滑并试试这个。我需要传递一个上下文而不是每次都新建它并且能够定义映射(实体框架) - 为了做到这一点,我需要继承然后覆盖DbContext类。我想保持它可插入任何我投入的上下文,这就是导致我这样做的原因。我有一个IRepository接口,它带有一个(实体)你常用的嫌疑人,并且它的实现依赖于IContextFactory ......

public interface IContextFactory<T> where T : DbContext
{
    T Context { get; }
}

在我的“EFRepository”

public class EFRepository<T, TContext> : IRepository<T> where T : class
        where TContext : DbContext
{

    public EFRepository(IContextFactory<TContext> contextFactory)
    {
    }
}

在我的地图中,我做了其中一项工作......

        x.For(typeof(IContextFactory<>)).Use(typeof(ContextFactory<>));
        x.For(typeof(IRepository<>)).Use(typeof(EFRepository<,>));

好的很酷。在我的单元测试中,我这样试试......

        var repository = ObjectFactory.GetInstance<EFRepository<Currency, EFContext>>();
        var repository2 = ObjectFactory.GetInstance<IRepository<Currency>>();

第一个有效,没问题。第二个,我受到了打击

提供的泛型参数的数量不等于泛型类型定义的arity。 参数名称:instantiation

我猜这是因为我告诉structmap,因为我传递了2,所以传递给IRepository的泛型是什么?我怎么做?我能这样做吗?

1 个答案:

答案 0 :(得分:3)

这应该是可能的,但它真的很混乱......除非有人知道更好的方法。

首先,您需要更改创建EFRepository<,>的方式。使用.Use(context => ...)重载,您可以访问context.BuildStack.Current.RequestedType.GetGenericArguments()之类的上下文,以获取您要访问的泛型类型。然后,您可以使用反射创建EFRepository<,>的新实例,并从上下文中获取IContextFactory

所以不管怎么样,

            ObjectFactory.Configure(x =>
            {
                x.For(typeof(IContextFactory<>)).Use(typeof(ContextFactory<>));
                x.For(typeof (IRepository<>)).Use(context =>
                    {
                        Type arg1 = context.BuildStack.Current.RequestedType.
                            GetGenericArguments()[0];

                        Type targetType =
                            typeof (EfRepository<,>).MakeGenericType(new[] {arg1, typeof (IContextFactory<>)});

                        return Activator.CreateInstance(targetType,
                                                        new[] {context.GetInstance(typeof (IContextFactory<>))});

                    });
                //x.For(typeof(IRepository<>)).Use(typeof(EfRepository<,>));
            });

        var repository = ObjectFactory.GetInstance<EfRepository<Currency, EfContext>>();
        var repository2 = ObjectFactory.GetInstance<IRepository<Currency>>();

会让你大部分时间到达那里。我认为你仍然需要在它工作之前为targetType的第二个泛型参数正确设置泛型。