具有依赖注入的实体框架ObjectContext [英] Entity Framework ObjectContext with Dependency Injection

查看:144
本文介绍了具有依赖注入的实体框架ObjectContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗯,好像我被困在我的应用程序结构中。以下是我要做的:




  • UI层:ASP.NET Webforms网站。

  • BLL:在DAL上调用存储库的业务逻辑层。

  • DAL:.EDMX文件(实体模型)和具有Repository类的ObjectContext,用于抽取每个实体的CRUD操作。
  • 实体:POCO实体。持久性无知。由Microsoft的ADO.Net POCO实体生成器生成。



我想在我的存储库中为每个HttpContext创建一个obejctcontext,以防止性能/线程[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());
返回HttpContext.Current.Items [ocKey]作为MyDBEntities;
}
}

问题是我不想访问HttpContext在我的DAL(存储库所在的位置)。但是我必须以某种方式将HttpContext传递给DAL。根据我的问题的答案这里,我必须使用IoC模式。理想情况下,我想在多层架构中实现像这个这样的东西。



我已经检查了Autofac,这似乎非常有希望。 但是我不知道如何实现这一点(传递Httpcontext以确保一个ObjectContext在HttpContext中被实例化)在多层架构中。有人可以给我一些关于如何实现的工作示例吗?如何在DAL中不知道HttpContext,而不直接访问DAL中的HttpContext?我觉得我在设计一个多层次的解决方案中有些失落。

解决方案

我从来没有使用IoC容器与WebForms所以得到这个一些高层次的解决方案,这可能会进一步改善。



您可以尝试创建一些IoC提供商作为单身人士:

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

私人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 将必须包含以下部分(配置基于您的上一篇文章):

 < configuration> 
< configSections>
< section name =castletype =Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,Castle.Windsor/>
< / configSections>

< castle>
< components>
< component id =DalLayer
service =MyDal.IDalLayer,MyDal
type =MyDal.MyDalLayer,MyDal
lifestyle =PerWebRequest>
<! -
这里我们定义DalLayer的生活方式是PerWebRequest,所以每个
时间容器在同一个Web请求
处理中解析IDalLayer接口,它返回相同的实例DalLayer类
- >
< parameters>
< connectionString> ...< / connectionString>
< / parameters>
< / component>
< component id =BusinessLayer
service =MyBll.IBusinessLayer,MyBll
type =MyBll.BusinessLayer,MyBll/>
<! -
只是BusinessLayer收到IDalLayer作为
构造函数参数的示例。
- >
< / components>
< / castle>

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

这些接口和类的实现可能如下所示:

  public IDalLayer 
{
IRepository< T> GetRepository< T>(); //使用通用存储库的简化解决方案
Commint(); //工作单位
}

// DalLayer持有对象上下文。根据PerWebRequest的生活方式,您可以
//在请求处理过程中解决此类数次,您仍然会
//获取相同的实例=单个ObjectContext。
public class DalLayer:IDalLayer,IDisposable
{
private ObjectContext _context; //创建存储库时使用上下文

public DalLayer(string connectionString){...}

...
}

公共接口IBusinessLayer
{
//每个服务实现将从构造函数获取必要的
//存储库。
// BusinessLayer将在创建服务时传递它们
// instance

//某些业务服务公开UI层的方法
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)。


Well, it seems like I'm stuck in my application structure. Here's what I want to do:

  • UI layer: An ASP.NET webforms website.
  • BLL: Business logic layer which calls the repositories on DAL.
  • DAL: .EDMX file (Entity Model) and ObjectContext with Repository classes which abstract the CRUD operations for each entity.
  • Entities: The POCO Entities. Persistence Ignorant. Generated by Microsoft's ADO.Net POCO Entity Generator.

I'd like to create an obejctcontext per HttpContext in my repositories to prevent performance/thread [un]safety issues. Ideally it would be something like:

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 ;
    }
}  

The problem is the I don't want to access HttpContext in my DAL (Where the repositories are located). But I have to somehow pass HttpContext to DAL. based on the answer to my question here, I have to use IoC pattern. Ideally I'd like to achieve something like this in amulti-layered architecture.

I've checked out Autofac and it seems very promising. But I'm not sure how could I achieve this (Passing Httpcontext to make sure one ObjectContext is instantiated per HttpContext) in a multi-layered architecture. Could anyone give me some working example on how to achieve this? How can I be aware of HttpContext in DAL without directly accessing the HttpContext in DAL? I feel like I'm a bit lost in designing a multi-layered solution.

解决方案

I have never used IoC container with WebForms so get this as some high level solution which should probably be futher improved.

You can try creating some IoC provider as singleton:

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")));
  }
}

Your web.config will have to contain sections like (the configuration is based on your 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>

Implementation of these interfaces and classes can look like:

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) { ... }

  ...
}

Than you can define base class for your pages and expose the business layer (you can do the same with any other class which can be resolved):

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

      return _businessLayer;         
  }

  ...
}

Complex solution whould involve using custom PageHandlerFactory to resolve pages directly and inject dependencies. If you want to use such solution check Spring.NET framework (another API with IoC container).

这篇关于具有依赖注入的实体框架ObjectContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆