业务逻辑层和数据访问层:循环依赖性[英] Business Logic Layer and Data Access layer: circular dependency

本文是小编为大家收集整理的关于业务逻辑层和数据访问层:循环依赖性的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有一些架构问题.在我的项目中,我有一个业务逻辑层(BLL),其中包含我的所有业务规则,模型和接口的OO API.每个对象都有静态方法,例如getByid返回所述对象的实例.每个对象还具有保存和删除之类的方法.这是非常简单的OO代码.

现在,我有一个dataAccess层(DAL),其中包含在一个单独的名称空间中,对于每个BLL对象,我都有一个Dataclass或"存储库",该dataclass或"存储库"执行GetById并保存命令.因此,从某种意义上说,BLL保存和getByid方法是Dataclass方法周围的薄层.

public static NewsItem GetByID(int id)
{
       return DataFactory.GetNewsItemRepository().GetNewsItemById(id);
}

为了使数据类别返回BLL对象,他们需要知道BLL.所以现在我们有:

gui ---> bll <----> dal

DataFactory仅返回实现接口的对象,因此我可以隐藏实现详细信息,例如" Oraclenewsitemrepository".

但是,自从我启动面向对象的编程以来,现在一直在困扰我的事情.在我目前的解决方案中,BLL和DAL都需要彼此了解.这是一个循环依赖性,这是避免循环依赖性的最佳实践.另外,我只想公开接口(和我的数据效果),而不是我的课程.这可以通过将DAL层放在单独的组件中来完成.这是有道理的.但是,Visual Studio不允许两个组件互相推荐.另一个问题: c#内部访问修饰符

不知何故,我认为我的整个数据访问模式错误.感觉就像我正在使用诸如datamappers之类的其他东西来解决Activerecord模式.我在马丁·福勒(Martin Fowler)的网站上花费了很多时间,但是这些模式非常通用,并用非常抽象的UML图进行了说明.

他们无法解决我的问题.也许我有点肛门,没有"完美的数据访问模式"之类的东西.我现在做的似乎并没有错.但是我现在如何做事,似乎没有……

有什么想法?

推荐答案

我认为您的数据访问模式很好.您不做的是将BLL耦合到口腔呼吸.您正在与DAL接口耦合.绝对需要一定的耦合,否则您永远无法完成任何操作.

我假设您的DataFactory和InewSitemrepository类都存在于您的DAL层之外.以下是我的解决方案如何组织的示例.我不使用ActivereCord,所以这可能不完全适合您.

Core (Project)
  Domain
    Business Entities
  Data
    Repository Interfaces
    **Your DataFactory**

OracleData (Project)
  Data
    Oracle Repository Implementations

SqlData (Project)
  Data
    Sql Repository Implementations

UI (Project)

希望这会有所帮助.

其他推荐答案

我认为:

数据访问层(DAL)应使用以下操作在POCO(普通旧CLR对象)上操作:SaveNewsItem ( NewsItemDAO newsItemDAO ). POCOS是您的DAO(数据访问对象).

业务层应包含将数据访问对象(DAO)转换为富业务对象的逻辑,该对象可能只是DAO以及某些操作以及任何装饰/丰富的操作.

DAL应该对业务逻辑层根本不了解.从理论上讲,它应该能够从任何客户那里调用.例如,如果您想将DAL与应用程序分开并将其部署为单独的服务,该服务通过WCF公开?

如前所述,DAL操作,例如BO应通过接口访问Safenewsitem,也许是通过依赖注入/IOC访问.

其他推荐答案

您可以使用接口/依赖注入解决问题.

您的业务层(BL)包含DAL(可能以上)DAL需要实现的数据访问(DA)接口. DAL项目具有对BL的项目引用,因此它们可以吐出业务对象(BOS)并实现DA接口.

您的BOS可以调用DataFactory,可以通过依赖注入或反射实例化DA对象.

我在工作中的许多应用程序中都使用了这种模式(基于Web的和智能客户),并且可以很好地工作.

本文地址:https://www.itbaoku.cn/post/627612.html

问题描述

I’m having a little Architecture problem. In my project I have a Business Logic Layer (BLL) that contains all my business rules, models and OO API for the interface. Each object has static methods like getById that return an instance of said object. Each object also has methods like save and, delete. This is very straightforward OO code.

Now I have a DataAccess layer (DAL), contained in a separate namespace, for each BLL object I have a DataClass or “Repository” which executes the getById and save commands. So in a way, the BLL save and getById methods are a thin layer around the DataClass methods.

public static NewsItem GetByID(int id)
{
       return DataFactory.GetNewsItemRepository().GetNewsItemById(id);
}

In order for the DataClasses to return BLL objects, they need to know the BLL. so now we have:

GUI ---> BLL <---->DAL

The DataFactory only returns objects that implement an Interface, so I can hide implementation details like “OracleNewsItemRepository”.

But now for the thing that has been bugging me ever since I started Object Oriented programming. In my current solution, both BLL and the DAL need to know each other. This is a Circular Dependency, and it is best practice to avoid circular dependencies. Also I only want to expose the interfaces (and my DataFactory) and not my classes. This can be done by placing the DAL layer in a separate Assembly. Which would make sense. However, Visual Studio does not allow two Assemblies to refer eachother. Another question about this: C# internal access modifiers

Somehow I think I got my whole data access pattern wrong. It feels like I am convoluting the ActiveRecord pattern with other stuff like DataMappers. I have spent a lot of time on Martin Fowler’s site, but those patterns are described very generic and are illustrated by a very abstract UML diagram.

They don’t solve my problem. Maybe I’m a bit anal, and there is no such thing as a “perfect data access pattern”. And what I do now doesn’t seem terribly wrong. But how I do things now, seems off…

Any ideas?

推荐答案

I think your data access pattern is fine. What you are not doing is coupling your BLL to the OracleDAL. You are coupling to the DAL interfaces. A certain bit of coupling is absolutely required or you could never get anything done.

I assume that your DataFactory and the INewsItemRepository classes exist outside your DAL Layer. The following is an example of how my solutions are organized. I don't use ActiveRecord, so this may not suit you perfectly.

Core (Project)
  Domain
    Business Entities
  Data
    Repository Interfaces
    **Your DataFactory**

OracleData (Project)
  Data
    Oracle Repository Implementations

SqlData (Project)
  Data
    Sql Repository Implementations

UI (Project)

Hope this helps.

其他推荐答案

In my opinion:

The Data Access Layer (DAL) should operate on POCOs (Plain old CLR objects) using operations such as: SaveNewsItem ( NewsItemDAO newsItemDAO ). The POCOs are your DAOs (Data Access Objects).

The Business Layer should contain the logic to convert a Data Access Object (DAO) into a rich business object, which is probably just the DAO plus some operations as well as any decoration/enrichment.

The DAL should have no knowledge at all about the Business Logic Layer. It should, in theory, be able to be called from any client. For example, what if you wanted to seperate the DAL from the application and deploy it as a seperate service exposing itself via WCF?

As mentioned, the DAL operations, e.g. SaveNewsItem should be be accessed by the BO via interfaces, perhaps via dependency injection/IoC.

其他推荐答案

You can use interfaces/dependency injection to solve your problem.

Your business layer (BL) contains the data access (DA) interfaces that the (possibly more than one) DAL need to implement. The DAL projects have project references to BL so that they can spit out business objects (BOs) and implement the DA interfaces.

Your BOs can call DataFactory, which can instantiate a DA object via dependency injection or reflection.

I have used this pattern in many of our applications here at work (both web-based and smart-client), and it works beautifully.