4

IDbSet<>Entity Framework のインターフェイスを使用して汎用リポジトリ パターンを実装したいと考えています。

IDbSet<T>Autofacに尋ねると、解決してからIDbContextそのメソッドを呼び出してSet<T>、具体的なタイプを返す必要がありますIDbSet<T>

例として、次のようなことを行う必要があります。

builder.Register<IDbSet<T>>(context => context.Resolve<IDbContext>().Set<T>());

Autofacでこれを達成するにはどうすればよいですか?

4

1 に答える 1

3

この回答に基づいているようです: https://stackoverflow.com/a/7997162/872395

IRegistrationSource唯一の解決策は、閉じた登録を作成するカスタムを作成することです。

public class DbSetRegistrationSource : IRegistrationSource
{
    public bool IsAdapterForIndividualComponents
    {
        get { return true; }
    }

    public IEnumerable<IComponentRegistration> RegistrationsFor(
        Service service,
        Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
    {
        var swt = service as IServiceWithType;
        if (swt == null || !swt.ServiceType.IsGenericType)
            yield break;

        var def = swt.ServiceType.GetGenericTypeDefinition();
        if (def != typeof(IDbSet<>))
            yield break;

        // if you have one `IDBContext` registeration you don't need the
        // foreach over the registrationAccessor(dbContextServices)

        yield return RegistrationBuilder.ForDelegate((c, p) =>
        {
            var dBContext = c.Resolve<IDBContext>();
            var m = dBContext.GetType().GetMethod("Set", new Type[] {});
            var method = 
                m.MakeGenericMethod(swt.ServiceType.GetGenericArguments());
            return method.Invoke(dBContext, null);
        })
                .As(service)
                .CreateRegistration();
    }
}

使い方はとても簡単です:

var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterSource(new DbSetRegistrationSource());
containerBuilder.RegisterType<DbContext>().As<IDBContext>();
var container = containerBuilder.Build();
于 2013-04-26T05:45:04.637 に答える