ASP.NET网站,EF,分层架构,我的设计还可以,还是应该更正?

时间:2011-07-24 22:38:07

标签: asp.net entity-framework architecture

我有一个DAL项目,实体数据模型上下文与EF 4.1

绑定

我提供了通过“业务”项目访问此上下文的方法。

我的问题如下:

我想我不应该从Business项目以外的地方引用DAL项目,所以我的想法是,我可以将“DataContract”接口添加到我已有的Common项目中,在DAL项目中引用该项目,扩展EF为我自动生成的部分类,继承与每个部分相对应的DataContracts,并使用这些DataContracts作为Business项目中操作的返回值,从而隔离DAL项目并避免将其紧密耦合到业务或网络项目

我的想法是正确的还是我离开了?

更新在重新阅读我自己的问题时,我发现这种难以理解的问题,这是我如何使用模型中的一个实体进行的示例:

该实体是:

namespace Application.Website.Main.Common.DataContracts
{
    public interface IServerApplication
    {
        string Id { get; set; }
        string ApplicationName { get; set; }
        byte MaxAccountsPerUser { get; set; }
        bool Enabled { get; set; }
    }
}

这将在Application.Website.Main.Common项目中。

在DAL项目中,我将引用Common项目,并将ServerApplication的部分类扩展为从该接口继承,无需进一步更改。

namespace Application.Website.Main.DAL
{
    public partial class ServerApplication : IServerApplication
    {

    }
}

在Business项目中,我将引用DAL和Common项目,并且我将这些DataContracts用作返回类型:

namespace Application.Website.Main.Business.Entities
{
    public class ServerApplication
    {
        public static IEnumerable<IServerApplication> Enabled()
        {
            var context = HttpContext.Current.GetDataContext();
            return context.ServerApplications.Where(a => a.Enabled);
        }
    }
}

为了完整性,这是放置在DAL项目中的GetDataContext()扩展方法:

public static class HttpContextExtensions
{
    internal const string _contextDataKey = "dataContext";

    public static EntityDataModelContext GetDataContext(this HttpContext httpContext)
    {
        if (httpContext.Items[_contextDataKey] == null)
            httpContext.Items.Add(_contextDataKey, new EntityDataModelContext());

        return (EntityDataModelContext)httpContext.Items[_contextDataKey];
    }
}

顺便问一下,我应该在哪里尝试/捕捉? 是否应该对使用数据上下文的每个业务级方法进行此操作? 或者在其他地方?
在这个级别处理异常的最佳方法是什么?

更新我在逻辑中发现了一个漏洞。如果我想要在给定实体的Business类中有一个方法,那么它必须是静态的和/或接口的扩展方法。像这样:

namespace Application.Website.Main.Business.Entities
{
    public class MembershipUser
    {
        public static int GetRequestCount(this IMembershipUser user)
        {
            var context = HttpContext.Current.GetDataContext();
            return context.ServerAccountRequests.Count(r => r.MembershipUserId == user.UserId);
        }
    }
}

或者,只是传递我查询所需的最少信息:

namespace Application.Website.Main.Business.Entities
{
    public class MembershipUser
    {
        public static int GetRequestCount(Guid userId)
        {
            var context = HttpContext.Current.GetDataContext();
            return context.ServerAccountRequests.Count(r => r.MembershipUserId == userId);
        }
    }
}

但是我怎样才能创建一个类,所以我可以使用实例方法,比如user.GetRequestCount()?然后DataContract需要是一个类而不是一个接口...或者我可能应该让这个类继承DataContract,但是我必须实现它的所有成员,我不打算这样做再次,因为这已经由EF在DAL级别处理

1 个答案:

答案 0 :(得分:0)

  

我想我不应该从某个地方引用DAL项目   除了商业项目......

取决于您如何引用它。简而言之,即使您的业务逻辑(BL)不应该引用DAL的物理实现,它应该引用定义DAL的接口;然后应该动态加载具体的破坏。

假设这个项目的规模超出了微不足道的程度 - 无论如何你仍然可以编写小型的PoC等。

  

我可以将“DataContract”接口添加到Common项目中   有

我在自己的程序集中定义数据契约,而不是在一个公共项目中定义,否则所有引用公共“知道”数据契约的东西(就是你真正想要的东西),如果你有任何依赖关系数据合同然后引用公共的所有内容也将获得那些额外的不需要的依赖项。

虽然我定义数据合同应该是一个单独的程序集,但DTO / POCO对象可能是共同的;我以前做过这个并且有很好的结果,因为我使用这些对象在不同的​​层之间抛出数据 - 而不仅仅是在DAL和BL之间。

你的amin应该是保持所有数据访问权限。具体的DAL实现中的EF引用(如SQL)。