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