0

Ну, похоже, что я застрял в структуре приложения. Вот что я хочу сделать:Entity Framework ObjectContext с впрыском зависимостей

  • UI layer: веб-сайт ASP.NET.
  • BLL: уровень бизнес-логики, который вызывает репозитории на DAL.
  • DAL: .EDMX-файл (Entity Model) и ObjectContext с классами репозитория, которые абстрагируют операции CRUD для каждого объекта.
  • Сущности: организации POCO. Настойчивость Невежественная. Создано Microsoft ADO.Net POCO Entity Generator.

Я хотел бы создать 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, чтобы убедиться, что один объект ObjectContext создан для HttpContext) в многоуровневой архитектуре. Может ли кто-нибудь дать мне какой-нибудь рабочий пример о том, как этого достичь? Как я могу знать HttpContext в DAL без прямого доступа к HttpContext в DAL? Я чувствую, что немного теряю при разработке многоуровневого решения.

ответ

3

Я никогда не использовал контейнер IoC с WebForms, поэтому сделайте это как решение на высоком уровне, которое, вероятно, должно быть улучшено.

Вы можете попробовать создать какой-то поставщик IoC как синглтон:

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

    ... 
} 

Комплексное решение whould предполагают использование пользовательских PageHandlerFactory для разрешения страниц непосредственно и инъекции. Если вы хотите использовать такое решение, проверьте Spring.NET framework (другой API с контейнером IoC).

+0

Спасибо Ladislav. Если бы я мог, я бы это сделал +10! – Kamyar