2012-04-04 29 views
1

我試圖做Autofac如下:Autofac:解決通用接口與可選參數,使用工廠代表

我有一個類的UnitOfWork:

public class UnitOfWork : IUnitOfWork 
    { 
    IContext contextA { get; set ;} 
    IContext contextB { get; set ;} 

    public UnitOfWork(IContext contextA, IContext contextB) 
    { 
    this.contextA = contextA; 
    this.contextB = contextB; 
    } 

    public void Save() 
    { 
    this.contextA.Save(); 
    this.contextB.Save(); 
    } 

    ... 
    } 

我也有一個泛型類GenericRepo :

public class GenericRepo<T> : IRepo<T> 
    { 
    private IContext context; 

    public GenericRepo(IContext context) 
    { 
    this.context = context; 
    } 
    } 

沒有輸入接口,但他們在那裏。

然後,我有這些代表:

public delegate IUnitOfWork IUnitOfWorkFactory(); 

public delegate IRepo<T> IRepoFactory<T>(IUnitOfWork unitOfWork = null); 

現在的問題是這樣的:

我需要能夠創建存儲庫。根據通用存儲庫的類型,它必須使用不同的上下文。我不希望調用代碼必須知道回購所使用的上下文,所以我不能使用上下文作爲參數,它必須是UnitOfWork。

但是,因爲通用回購是通用的,它不知道從UnitOfWork獲得什麼上下文,所以它必須通過它的構造函數獲取上下文,而不是UnitOfWork。

此外,有時調用代碼不關心UnitOfWork(因爲它不需要保存),在這種情況下,UnitOfWork必須實時創建 - 它仍然需要一個來獲取其數據從。

所以我需要這個工作:

public void TestCode(IRepoFactory<TypeA> repoFacA, IRepoFactory<TypeB> repoFacB, IUnitOfWorkFactory uowFactory) 
    { 
    IRepo<TypeA> repoA = repoFacA(); //repoA has contextA from a new UnitOfWork 
    IRepo<TypeB> repoB = repoFacB(); //repoB has contextB from a new (different) UnitOfWork 

    IUnitOfWork uow = uowFactory(); 
    IRepo<TypeA> repoA_2 = repoFacA(uow); //repoA_2 has contextA from uow 
    IRepo<TypeB> repoB_2 = repoFacB(uow); //repoB_2 has contextB from uow 
    } 

換句話說,我需要能夠調用帶有參數的泛型委託,並根據類型,它需要使用構造類來自該參數的屬性。

它還需要在沒有參數的情況下工作,在這種情況下,Autofac必須解析並使用參數本身。

有關如何在AutoFac中註冊所有這些的任何想法?

+0

你有使用HTTP鍵認爲://咕。gl/aT80h或元數據http://goo.gl/1RU06? – cecilphillip 2012-04-05 03:23:51

回答

2

好吧,自己找到它。

這是我的註冊代表:

 builder.Register((b, p) => new GenericRepo<TypeA>(((((p.First() as ConstantParameter)).Value as UnitOfWork) ?? b.Resolve<IUnitOfWork>()).ContextA)).As<IRepo<TypeA>>(); 
     builder.Register((b, p) => new GenericRepo<TypeB>(((((p.First() as ConstantParameter)).Value as UnitOfWork) ?? b.Resolve<IUnitOfWork>()).ContextB)).As<IRepo<TypeB>>(); 

編輯:

或者更好的,做它的第一個通用的方法:

builder.RegisterGeneric(typeof(GenericRepository<,>)).WithParameter((pi, icc) => true, (pi, icc) => (((((icc as IInstanceLookup).Parameters.First()) as ConstantParameter).Value as IUnitOfWork) ?? icc.Resolve<IUnitOfWork>()).ContextA).As(typeof(IEntityRepository<,>)); 

第一個參數'WithParameter()'必須在那裏,它必須返回true。我想如果我想過濾哪些參數,我必須在那裏做。

無論如何。如果你有很多需要ContextA的類型,並且只有一些需要contextB,才能爲A進行通用註冊,然後爲B添加異常。如何使這個更乾淨或更容易對眼睛

建議總是歡迎:-)