EF N-Tier架构

时间:2015-02-05 07:06:41

标签: c# entity-framework architecture n-tier-architecture

简介

我们需要构建一个n层应用程序,因为我们希望在多个平台上共享我们的BL并且只编写一次DAL。我已经就这个问题做了一些研究。

正如可以在Davide Piras的帖子中看到的那样:MVC3 and Entity Framework每个VS解决方案必须至少有4层。到目前为止一切都很好。

他还指出,DAL项目是唯一允许甚至知道正在使用EF的项目。

问题1:

我假设,'Interfaces'项目的接口是我的EF实体的1对1表示,我对此是否正确?另外,这些接口应该用作不同层之间的类型吗?

问题2:

MSDN建议DbContext的生命周期应该是每个WebApp请求的一个上下文,以及WPF或WinForms项目中每个表单的一个上下文。那么,如何在不将“System.Data.Entity”添加到GUI层的情况下实现这一目标呢?

Thnx提前!

2 个答案:

答案 0 :(得分:3)

您需要将Unit of WorkRepository模式与StructureMapUnity等依赖注入框架一起使用。

基本上,您需要做的是创建接口:

public interface IUnitOfWork
{
    void SaveChanges();
}

public interface IRepository<TItem>
{
    TItem GetByKey<TKey>();

    IQueryable<TItem> Query();
}

现在,在您的DbContext类中,实现上面的接口以及业务层中的某个位置注册接口的实现:

public void RegisterDependencies(Container container)
{
    // Container is a Structure Map container.
    container.ForRequestedType<IUnitOfWork>()
        .CacheBy(InstanceScope.HttpContext)
        .TheDefaultConcreteType<DbContext>();    
}

有关如何配置实例范围的信息,请参阅StructureMap Scoping Docs

现在,在所有代码到位的情况下,需要执行某些数据操作的每个Business Layer类都如下所示:

public class SomeService
{
    public SomeService(IRepository<SomeItem> repository, IUnitOfWork unitOfWork)
    {
        this.repository = repository;
        this.unitOfWork = unitOfWork;
    }

    public void MarkItemCompleted(int itemId)
    {
        var item = repository.GetByKey(itemId);
        if(item != null)
        {
            item.Completed = true;
            unitOfWork.SaveChanges();
        }
    }
}

现在,隐藏工厂背后的服务创建:

public class ServiceFactory
{
    private readonly Container container;// = initialize the container

    public TService CreateService<TService>()
    {
        return container.GetInstance<TService>();
    }
}

在GUI层中,只调用通过ServiceFactory创建的服务类的方法;如果您的GUI是ASP.NET MVC项目,则不需要创建ServiceFactory类 - 您可以从DefaultControllerFactory派生并覆盖GetControllerInstance方法。有关示例,请参阅the answer here

答案 1 :(得分:2)

首先不要!!! 在多个平台上分享您的DAL。分享使用DAL的BL。只要您的BL代表您的应用程序要求的解决方案,您就不需要暴露您的DAL,请不要。暴露DAL还有一个缺点,即向黑客暴露更多漏洞,直接访问DAL为您的BL中的业务逻辑,控制和验证提供了btpass机制。

回答1: 可能但不需要。考虑到SOA,我建议使用DTO。它们是实体或更复杂的几个和/或部分实体的复合类。如果您使用实体,这可以让您更灵活地通过BL提供信息(您可以通过一次方法调用一次发送几个部分的数据)并隐藏第三方用户的实体(也包括数据库结构),从而提供更好的安全感。 / p>

回答2: 再次,考虑到SOA,不要根据您的用户界面构建BL / Service方法。 BL(顾名思义)根据“工作如何完成”而不是“用户如何在屏幕上完成工作”提供数据。如果您尝试从GUI管理数据,您也将开始违反N层架构。 请勿!!! 使用DAL之外的任何数据特定类和/或方法。这将是分层的真正用法。

问候。