Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# efn层体系结构_C#_Entity Framework_Architecture_N Tier Architecture - Fatal编程技术网

C# efn层体系结构

C# efn层体系结构,c#,entity-framework,architecture,n-tier-architecture,C#,Entity Framework,Architecture,N Tier Architecture,导言 我们需要构建一个n层应用程序,因为我们希望在多个平台上共享我们的BL,并且只编写一次DAL。我已经在这个问题上做了一些研究 正如在Davide Piras的帖子中所读到的:每个VS解决方案必须至少有4层。到目前为止还不错 他还表示,DAL项目是唯一一个被允许知道EF正在使用的项目 问题1: 我假设“接口”项目的接口是我的EF实体的1对1表示,我的说法正确吗?此外,这些接口应作为不同层之间的类型使用 问题2: 建议在WPF或WinForms项目中,DbContext的生存期应为每个WebAp

导言

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

正如在Davide Piras的帖子中所读到的:每个VS解决方案必须至少有4层。到目前为止还不错

他还表示,DAL项目是唯一一个被允许知道EF正在使用的项目

问题1:

我假设“接口”项目的接口是我的EF实体的1对1表示,我的说法正确吗?此外,这些接口应作为不同层之间的类型使用

问题2:

建议在WPF或WinForms项目中,DbContext的生存期应为每个WebApps请求一个上下文,每个表单一个上下文。那么,如何在不向GUI层添加“System.Data.Entity”的情况下实现这一点呢


提前通知

首先不要通过多个平台共享您的DAL。共享使用DAL的BL。只要您的BL代表您的应用程序需求的解决方案,您就不需要公开您的DAL,请不要公开。此外,暴露DAL的缺点是向黑客暴露更多漏洞,直接访问DAL为BL中的业务逻辑、控制和验证提供了btpass机制

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

答案2: 同样,考虑到SOA,不要根据用户界面构造BL/服务方法。BL(顾名思义)根据“如何完成工作”而不是“用户如何在屏幕上完成工作”提供数据。如果您试图从GUI管理数据,也将开始违反N层体系结构不要使用DAL之外的任何数据特殊类和/或方法。这将是分层的真正用途


关于。

您需要将
工作单元
存储库
模式与依赖项注入框架(如or)结合使用

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

public interface IUnitOfWork
{
    void SaveChanges();
}

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

    IQueryable<TItem> Query();
}
public void RegisterDependencies(Container container)
{
    // Container is a Structure Map container.
    container.ForRequestedType<IUnitOfWork>()
        .CacheBy(InstanceScope.HttpContext)
        .TheDefaultConcreteType<DbContext>();    
}
有关如何配置实例的作用域,请参见

现在,所有这些代码就绪后,需要执行某些数据操作的
业务层
类的每个类都将如下所示:

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();
        }
    }
}
公共类服务
{
公共服务(IRepository存储库、IUnitOfWork unitOfWork)
{
this.repository=存储库;
this.unitOfWork=unitOfWork;
}
public void markitempleted(int itemId)
{
var item=repository.GetByKey(itemId);
如果(项!=null)
{
item.Completed=true;
unitOfWork.SaveChanges();
}
}
}
现在,隐藏工厂后面的服务创建:

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

    public TService CreateService<TService>()
    {
        return container.GetInstance<TService>();
    }
}
公共类服务工厂
{
私有只读容器容器;//=初始化容器
公共TService CreateService()
{
返回container.GetInstance();
}
}

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

Thnx有关否决票,如果我遗漏了什么,请发表评论。。我已经投入了一些精力和时间来问这些问题。谢谢你的快速回答!很抱歉,我想说的不是像向其他GUI公开DAL那样共享DAL,而是只编写一次!我的错。如果我帮了忙,我很高兴。是的,你帮了忙;)。我会在几个小时内标记为答案,我仍在等待更多的意见,我认为当一个问题仍然没有答案时,人们会更加渴望。没问题。我答应帮忙,不是为了名誉。祝你有一个愉快的一天。是的,它必须在BL中完成。任何UI都只会看到你的BL(作为API),并且只会与此层通信。如何转换数据取决于您使用的语言和/或您的开发首选项。在我当前的项目中,我们只使用ADO.NET,所以我通过存储过程从数据库中获取数据,并从DAL返回接口。在BL中,我从接口创建模型(我的UI仅限于ASP.NET MVC!!!)并返回它。但是我更倾向于使用ORM工具(比如像DAL这样的实体框架)并编写LinQ查询来获得[this]()结构.Thnx,以获得清晰的响应!这很有帮助。我已经遇到了寄存和UOW模式。我认为回购协议的实施应该在DAL中,对吗?再次使用Thnx。@MarkRijsmus,是的,它应该在数据访问中。