interaction between data data acess layer and business layer - c#

i'm beginner in repository and layerd application and i don't inderstand well which is the interaction and the relationship between the repositories and business layer classes
Here is an example for purchaese order in 3 layers and I want to review whether correct or not and your correction
for DataAcesslayer
repository OrderRepositolry
Namespece Dal
{
       Public class RepositoryOrder
       {
              POrderContext context = new POrderContext ();
 
              Public IEnumrebale <Order> GetAll ()
              {
                   Context.Orders;
              }
// Following code
       }
}
for the item of order repositories code :
namespece Dal
{
public class RepositoryOrderItem
{
POrderContext context = new POrderContext();
public IEnumrebale<OrderItem> GetAllItemById(Order o)
{
context.OrderItems.where(i => i.OrderId == o.Id);
}
public OrderItem GetItemById(int id)
{
context.OrderItems.Find(id);
}
//Following code
}
}
for businessLayer here is classOrderBLL code:
namespace BLL
{
public class OrderBLL
{
RepositoryOrder repoOrder = new RepositoryOrder();
RepositoryOrderItem repoItem = new RepositoryOrderItem();
public IList<Order> GetAll()
{
return repoOrder.GetAll();
}
public decimal GetPrixTotal(Order order)
{
var query = from item in repoItem.GetAllItemById(order)
select sum(item=>item.Prix * item.Quantite);
return query;
}
}
}
does the total price calculation is done at the level of repository
or at the level of BLL (we can make this request linq with context
in the repository)?
CRUD method is done at repository and they are called at BLL from
repository is it right?
does the where method in linq corresponds to logical business or
repository (data access layer) since it determines certain rules in
the business?

I'm sure this question will be voted down as "primarily opinion based" but before that happens I'll jump in to give my "primarily opinion based" answer :-)
There are two ways to partition a database application and they depend on how complex and large it will be. Entity Framework examples tend to give a very simplistic model, where the EF Data classes are exposed to the Business layer which then exposes them to the View Model or other layers. This may be correct for simplistic applications but for more complex ones, and ones where the data storage method is not RDBMS (i.e. No-SQL) or where you want to create separation between business and repository data structures it is too simple.
The repository layer should have a set of classes which describe how the data is accessed from the repository. If you have an RDBMS these might be EF POCO classes, but if you have a web-service endpoint as your repository this may be SOAP documents, or REST structures, or other Data Transfer Object. For an RDMBS like SQL Server that uses exclusively stored procedures for accessing its data, the Repository layer might simply be a set of classes which mirror the naming and parameters, and data sets returned by the stored procedures. Note that the data stuctures returned by anything other than an RDBMS might not be coherent - i.e. a "Customer" concept returned by one method call in the repository might be a different data structure to a "Customer" returned by a different call. In this case the repository classes would not suit EF.
Moving to the business object layer - this is where you create a model of the business domain, using data classes, validation classes and process class models. For instance a Process class for recording a sales order might combine a Business Customer, Business Sales Order, Business Product Catalog data concepts and tie in a number of Validation classes to form a single atomic business process. These classes might (if you are doing a very lightweight application) be similar to data at the Repository layer but they should be defined seperately. Its in this layer you hold calculated concepts such as "Sales Order Total" or "VAT Calculation" or "Shipping Cost". They might, or might not, get stored into your Repository but the definition of what they mean are modelled in the business layer.
The business layer provides the classes whose data is copied across into a View Model. These classes again can be very similar (and in the simplest of cases, identical to) the repository classes, but in their job is to model the user interface and user interaction. They might contain only some of the data from the business data classes, depending on the requirements of the UI. These classes should carry out user interface based validation, which they might delegate to the business tier, or might add additional validation to. The job of these classes is to manage the state-machine that is the user interface.
My summary is that in a large scale system you have three sets of classes; data repository interaction, business model interaction, and user interface interaction. Only in the simplest of systems are they modelled as a single set of physical POCO classes.

Related

Building applications using multiple datasources for single objects

I'm struggling finding a right solution for my application architecture. For my application I have a single class for customers. The data for filling my customer objects are spread over multiple different types of datasources. The main part is exposed in a readonly Oracle database, other parts are exposed using a webservices and I need te save some extra data to another datasource (for instance a MS SQL database using entityframework) since I only have readonly rights for most datasouces (they are managed somewhere else).
For this reason I wanna build some kind of central library with connectors to all of my datasources for creating a centralized Customer Object to work with. So far so good for this idea (I think) but I can't find any documentation or example with best practices how to achieve such a solution.
EXAMPLE:
* Main Application (multiple applications)
- Central Business Logic Layer (Business-API)
* Webservice Connector
* Oracle Connector
* EntityFramework Connector
Does anyone know if there is some good reading material on this specific subject?
Kind regards
The specific problem you describe with customer objects sounds a lot like the one solved by the Data Mapper pattern, which is technically a kind of Mediator. Quoting from the Wikipedia page for Data Mapper:
A Data Mapper is a Data Access Layer that performs bidirectional transfer of data between a persistent data store (often a relational database) and an in memory data representation (the domain layer). The goal of the pattern is to keep the in memory representation and the persistent data store independent of each other and the data mapper itself. The layer is composed of one or more mappers (or Data Access Objects), performing the data transfer. Mapper implementations vary in scope. Generic mappers will handle many different domain entity types, dedicated mappers will handle one or a few.
Although the language of the problem above speaks of a persistent data store that's singular, there's no reason why it couldn't be several data locations (Mediator pattern hides the details from the collaborators).
There is an extension of this pattern, known as the Repository pattern:
I suggest the DAO-Pattern to abstract from any data access. The business logic should not be aware of any datasources. This is the most important aim. Anything else has to be subordinated.
You can create a constructor that accepts datasources like:
public class Customer
{
public Customer(OracleConnector oracle, WebSerivceConnector webservice, EntityConnector entity)
{
this.oracle = oracle;
this.webservice = webservice;
this.entity = entity;
}
public void Fetch()
{
// fetch data from oracle, webservice, and entity.
this.Name = oracle.GetCustomerName();
}
}
This way only Customer knows how to get the data, all the logic is in one place. You can even make it more testable and less coupling by creating interfaces for connectors.
public interface IOracleConnector
{
// add something here
string GetCustomerName();
}
public class OracleConnector
: IOracleConnector
{
// add the implementation here.
}
Then change Customer constructor to accepts IOracleConnector like:
public Customer(IOracleConnector oracle, WebSerivceConnector webservice, EntityConnector entity)
{
// your code here.
}
Now, you can create a mock to test Customer without actually connecting to the database.

Linq to Sql and separation of concerns - am I doing this right?

I have a project that I'm working on that I'm using LINQ to SQL for and I have set up business objects/models to use in my web app. I am looking for some feedback on how I've set all this up to see if it makes sense and if there's anything I should be doing differently.
Here's an example model:
public class User
{
private MyDataContext _db = new MyDataContext();
private MyLINQUserClass _user = new MyLINQUserClass();
public string Name
{
get
{
return _user.Name;
}
set
{
_user.Name = value;
}
}
public User(int UserID)
{
_user = _db.Where(u => u.UserID == UserID).FirstOrDefault();
if (_user == null)
{
_user = new MyLINQUserClass();
}
}
internal User(MyLINQUserClass user, MyDataContext db)
{
_db = db;
_user = user;
}
public void Save()
{
_db.SubmitChanges();
}
public static User Add(string Name)
{
MyDataContext _db = new MyDataContext();
MyLINQUserClass _user = new MyLINQUserClass();
_user.Name = Name;
_db.MyLINQUserTable.InsertOnSubmit(_user);
_db.SubmitChanges();
return new User(_user, _db);
}
public static IList<User> Get()
{
MyDataContext _db = new MyDataContext();
return _db.MyLINQUserTable.Select(u => new User(u, _db)).ToList();
}
}
For clarity, I am using this type of model already quite heavily in the project (the above is just an example I threw together for the post on the fly) and it works very well. My question is more of a "learning" question ... I know it works. I'm just not sure if there is something I should be doing differently that is better and if so, why.
Thoughts?
I suppose there are no right answers to this kind of questions. It is a matter of design, preference and requirements. I will try to show my view...
I always liked the Repository pattern to keep the concerns seperated. I would use a repository of type T to retrieve the T entities (talking generics). These would be the entities participating on my business model. In your case, I would have a UsersRepository class, returning User entities. This Data access layer (DAL) would handle my data access concern.
My business model would use the entities to do its business. In simple CRUD applications, maybe no other objects other the entities returned by my repositories would be needed. In more complicated applications, new classes would be needed, using the repositories of the DAL to retrieve data as entities. This business layer would handle my main business functionality concern (calculations etc).
Then, for display purposes, you could need perhaps another structure. For instance, if you follow the MVC pattern (you could also see the Microsoft article) you would need to create another model to fit your display purposes. This GUI layer following the MVC pattern would handle my graphical display concern.
Hope I helped!
This is the so-called Data Access Objects pattern. The User is a DAO to MyLINQUserClass which might be called the domain class.
The DAO pattern is designed for single responsibility: only the DAO "knows" the data layer while the domain class can concentrate on business logic. The domain class is persistence ignorant. So far, so good.
However, there are (at least) three great drawbacks of this pattern:
It tends to create lots of boilerplate code
It is hard to compose object graphs, because a DAO represents only one row in the database and fetching object graphs easily degenerates into one query per object or collection of child objects.
It is hard to work transactionally, because a DAO can't manage a transaction spanning an entire object graph. So you need some overarching layer to handle transactions.
Most ORMs however, have a different persistence-ignorance model than DAO. They have repositories and units of work. In L2S the Table is a basic repository and the context a unit of work. The "domain" classes, like MyLINQUserClass, can be considered persistence-ignorant. (Admitted, they are stuffed with boilerplate code that serves persistence and change tracking, but it is generated and it can practically be ignored). So all responsibilities for CRUD operations have been assigned, and there's no need for other objects carrying these responsibilities.
The way you implement it makes it extra hard to work with object graphs and transactions because each DAO has its own context, so you can't compose LINQ queries involving multiple DAO's in a way that the LINQ is translated into one SQL statement. And doing multiple save operations in one transaction is a challenge.
Conclusion
By using DAO in a linq-to-sql environment you're mixing CRUD responsibilities. You get all the disadvantages of the DAO pattern and can't exploit the power of the repository/UoW pattern to the full. I would strongly recommend to make a choice for one or the other, and I would choose L2S (well, actually I would choose Entity Framework).

Abstraction layer between repository and data access code

I try to isolate repository from actual data storage implementation. I have little problem to create some simple query with this abstraction.
Example I need list of orders with number of order lines in order.
Repository method returns list of OrderInfo objects.
class OrderInfo
{
string Title { get; set; }
int NumberOfLines { get; set; }
}
Data storage does not contain any field directly containing order line count so it must be calculated on the fly.
This can be easily archived with simple sql query (count + group by) when query is directly written into repository method.
If I try to create some kind of abstraction layer I got lost how to "define query without using any storage dependant thing with it including that it should return number of order lines for each order".
Or am I totally going to wrong direction?
If you want to allow the usage of IQueryable in your BLL (which I think it should), then you can define queries as much as you want. One of the criteria your DAL should then pass for it to be of usage with your BLL, is it should be able to take an IQueryable, and use it to read some data. This way you can 'be smart' in you BLL, and the DAL will be abstracted.
Example:
BLL - define it using interfaces. A generated context-interface provides you with all entities (=tables) in the system. The entities will be available with IQueryable<entityType>. The entities are defined using Entity Framework POCO's.
DAL - an Entity Framework context where the context implements the interface you defined in the BLL.
Each layer is in their own assembly. The DAL is wired up using some Dependency Injection.
Remember, this is just an example.
UPDATE
Read this article about the onion architecture, which is exactly what you're trying to do.

My entities have only setters and getters but no methods - design failure -

I have read this once:
"Don't leave entities as bags of getters and setters and put their methods in another layer unless you have a good reason to"
My customer, order, ... objects just get the data from the SqlDataReaders. They have only getter and setter.
My first question is which design approach does this follow when someone implements methods in entities AND what are these methods doing?
This way of thinking comes from the Domain Driven Design community.
In DDD you create a Domain Model that captures the functionality that your users request. You design your entities as having functionality and the data they need for it. You group them together in aggregates and you have separate classes that are responsible for construction (Factories) and querying (Repositories).
If you only have getters/setters you have an 'Anemic Domain Model'. Martin Fowler wrote about it in this article.
The problem with an Anemic Domain model is that you have the overhead of mapping your database to objects but not the benefits of it. If you don't use your entities as a real domain model, why don't you just use a DataTable or something for your data and keep your business logic in separate functions? An Anemic Domain model is an anti-pattern that should be avoided.
You also mention that you map the entities yourself. This blog explains why using an Object-Relational Mapping tool can really help. If you use Entity Framework with a Code First approach you can write a clean domain model with both data and functionality and map it to your database without much hassle. Then you will have the best of both worlds.
When you have methods as part of your model, you should only include model specific type of logic. For example, consider a bank account:
public class Account {
public AccountId Id { get; set; }
public Person Customer {get; set; }
public void Credit(Money amount) { ... }
public void Debit(Money amount) { ... }
}
Credit and Debit are model-specific logic (you won't find them anywhere else in the application), and should be encapsulated in the Account class.
You also mentioned that you used SqlDataReader within your model classes to get the data from the database. This is a big anti-pattern. Here are some problems you will encounter with this:
Violating Single Responsibility Principle - The model is now in-charge of representing the data and getting the data from the db.
How about querying children in your model? It gets messy.
You won't be able to change your data-access as easily.
Keep the model lean. Put the data access logic in a repository, i.e. AccountRepository.

Entity Framework in Layered Architectures

Recently I've read article "The Entity Framework In Layered Architecture" and there is written we can send EF-entities to client through WCF. But in many threads on Stackoverflow people tell that POCO(DTO)-objects should be used when we use WCF.
And I have some questions.
Why did Microsoft add DataContract attribute to EF-entities? Does Microsoft wanted us to use these objects everywhere in our applications? Or this is only for very simple applications and for rapid development?
If I use POCO-objects, should I create auto generated EF-Entities, POCO-Entities and after that use any mapping library between them? Or I should use only POCO-objects in all components of my application?
If I already have my own business entity, which has some methods, and it should be mapped to POCO object, on which layer should I convert POCO-object to my entity (for example, I have persistence layer, business logic layer, service layer(WCF), presenter layer (client, use WCF), UI layer)? Or I shouldn't make such my own entities?
Thanks in advance
1.Why did Microsoft add DataContract
attribute to EF-entities? Does
Microsoft wanted us to use these
objects everywhere in our
applications? Or this is only for very
simple applications and for rapid
development?
Generally speaking, it is a bad idea to expose your EF-Entities in the service layer because that hardly couples your service layer and model representation. so any changes done in the model ends affecting directly your services, not a good idea. also you will have to version your service layer in some moment, so avoid to expose the EF entities in your service layer.
2.If I use POCO-objects, should I create auto generated EF-Entities,
POCO-Entities and after that use any
mapping library between them? Or I
should use only POCO-objects in all
components of my application?
You can use POCO objects inside your service layer, to decouple it from any underlying layers (see Automapper, to cover the Entity-DTO mapping cost). but you could still use the autogenerated EF-entities among the data and business layers in your architecture. just try to not rely in EF specific features of your generated domain model in other layers different from data layer. to ease the migration to another ORM frameworks.
If I already have my own business
entity, which has some methods, and it
should be mapped to POCO object, on
which layer should I convert
POCO-object to my entity (for example,
I have persistence layer, business
logic layer, service layer(WCF),
presenter layer (client, use WCF), UI
layer)? Or I shouldn't make such my
own entities?
Service layer http://msdn.microsoft.com/en-us/library/ms978717.aspx. you would be using your domain model transparently among the server tier (persistence, business, service and presenter layers) of your application, and the only layer that will require you a DTO mapping is the service layer, see question 1. (additionally if you are using ViewModels inside your the presenter layer -nice idea- you will require to use POCOs-mapping in the presenter layer too).
You can have POCO entities handwritten and completely separated from the persistence layer. SDReys is right, using generated EF entities as your model is smelly.
Here is the rough layout for a simple POCO model and the context to support it.
public class MyApplicationContext : ObjectContext, IMyApplicationContext {
public MyApplicationContext() : base("name=myApplicationEntities", "myApplicationEntities")
{
base.ContextOptions.LazyLoadingEnabled = true;
m_Customers = CreateObjectSet<Customer>();
m_Accounts = CreateObjectSet<Account>();
}
private ObjectSet<Customer> m_Customers;
public IQueryable<Customer> Customers {
get { return m_Customers; }
}
private ObjectSet<Account> m_Accounts;
public IQueryable<Account> Accounts {
get { return m_Accounts; }
}
public Account CreateAccount(Customer customer) {
var account m_Accounts.CreateObject();
account.Customer = customer;
return account;
}
public Customer CreateCustomer() {
return m_Customers.CreateCustomer();
}
public void AddAccount(Account account) {
m_Accounts.AddObject(account);
}
public void AddCustomer(Customer customer) {
m_Customers.AddCustomer(customer);
}
}
public class Account {
public int Balance {get;set;}
virtual public Customer{get;set;}
}
public class Customer {
public string Name {get;set;}
virtual public List<Account> Accounts{get;set;}
}

Categories

Resources