0

好吧,看起來我被困在我的應用程序結構中。以下是我想要做的:具有依賴注入的實體框架ObjectContext

  • UI層:ASP.NET webforms網站。
  • BLL:在DAL上調用存儲庫的業務邏輯層。
  • DAL:.EDMX文件(實體模型)和ObjectContext與存儲庫類抽象每個實體的CRUD操作。
  • 實體:POCO實體。持久性無知。由Microsoft的ADO.Net POCO實體生成器生成。

我想創建一個obejctcontext每HttpContext在我的倉庫,以防止性能/線程[un]安全問題。理想情況下是這樣的:

public MyDBEntities ctx 
{ 
    get 
    { 
     string ocKey = "ctx_" + HttpContext.Current.GetHashCode().ToString("x"); 
     if (!HttpContext.Current.Items.Contains(ocKey)) 
      HttpContext.Current.Items.Add(ocKey, new MyDBEntities()); 
     return HttpContext.Current.Items[ocKey] as MyDBEntities ; 
    } 
} 

問題是我不想要訪問的HttpContext在我的DAL(凡庫的位置)。但我必須以某種方式將HttpContext傳遞給DAL。基於對我的問題here的回答,我必須使用IoC模式。理想情況下,我想在多層體系結構中實現諸如this之類的內容。

我已經簽出Autofac,它看起來很有希望。 但是我不確定在多層體系結構中如何實現這一點(通過Httpcontext確保每個HttpContext實例化一個ObjectContext)。任何人都可以給我一些關於如何實現這個目標的實例嗎?如何在不直接訪問DAL中的HttpContext的情況下知道DAL中的HttpContext?我覺得我在設計多層解決方案時有點遺憾。

回答

3

我從來沒有使用IoC容器與WebForms,所以得到這個作爲一些高層次的解決方案,應該可能進一步改進。

你可以嘗試創造一些國際奧委會提供的單身:

public class IoCProvider 
{ 
    private static IoCProvider _instance = new IoCProvider(); 

    private IWindsorContainer _container; 

    public IWindsorContainer 
    { 
    get 
    { 
     return _container; 
    } 
    } 

    public static IoCProvider GetInstance() 
    { 
    return _instance; 
    } 

    private IoCProvider() 
    { 
    _container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle"))); 
    } 
} 

web.config必須包含的部段(該配置是基於你的previous post):

<configuration> 
    <configSections>  
    <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> 
    </configSections> 

    <castle> 
    <components> 
     <component id="DalLayer" 
       service="MyDal.IDalLayer, MyDal" 
       type="MyDal.MyDalLayer, MyDal" 
       lifestyle="PerWebRequest"> 
     <!-- 
      Here we define that lifestyle of DalLayer is PerWebRequest so each 
      time the container resolves IDalLayer interface in the same Web request 
      processing, it returns same instance of DalLayer class 
      --> 
     <parameters> 
      <connectionString>...</connectionString> 
     </parameters> 
     </component> 
     <component id="BusinessLayer" 
       service="MyBll.IBusinessLayer, MyBll" 
       type="MyBll.BusinessLayer, MyBll" /> 
     <!-- 
      Just example where BusinessLayer receives IDalLayer as 
      constructor's parameter. 
     --> 
    </components> 
    </castle> 

    <system.Web> 
    ... 
    </system.Web> 
</configuration> 

這些接口的實現並且類可以看起來像:

public IDalLayer 
{ 
    IRepository<T> GetRepository<T>(); // Simplified solution with generic repository 
    Commint(); // Unit of work 
} 

// DalLayer holds Object context. Bacause of PerWebRequest lifestyle you can 
// resolve this class several time during request processing and you will still 
// get same instance = single ObjectContext. 
public class DalLayer : IDalLayer, IDisposable 
{ 
    private ObjectContext _context; // use context when creating repositories 

    public DalLayer(string connectionString) { ... } 

    ... 
} 

public interface IBusinessLayer 
{ 
    // Each service implementation will receive necessary 
    // repositories from constructor. 
    // BusinessLayer will pass them when creating service 
    // instance 

    // Some business service exposing methods for UI layer 
    ISomeService SomeService { get; } 
} 

public class BusinessLayer : IBusinessLayer 
{ 
    private IDalLayer _dalLayer; 

    public BusinessLayer(IDalLayer dalLayer) { ... } 

    ... 
} 

比你能定義基類爲您的網頁,並暴露業務層(你可以做同樣的與任何其他類可以解決):

public abstract class MyBaseForm : Page 
{ 
    private IBusinessLayer _businessLayer = null; 
    protected IBusinessLayer BusinessLayer 
    { 
    get 
    { 
     if (_businessLayer == null) 
     { 
     _businessLayer = IoCProvider.GetInstance().Container.Resolve<IBusinessLayer>(); 
     } 

     return _businessLayer;   
    } 

    ... 
} 

複雜的解決方案對子級涉及使用自定義PageHandlerFactory直接解決網頁和注入依賴關係。如果你想使用這樣的解決方案,請檢查Spring.NET框架(帶IoC容器的另一個API)。

+0

謝謝拉迪斯拉夫。如果可以的話,我會+10! – Kamyar 2011-01-07 17:46:27