I'm working on an ASP.NET MVC project in C# with an N-tier architecture.
A class (EmployeeRepo) in the database project has many functions.
Each function's natural result from the transaction is a dataset, but they are converted as per the need.
The return types are:
Dataset (with one or more tables)
DataTable
int
bool
Object (single employee)
List<Object> (list of employees)
Which is better among the two or is there a standard to follow:
Return the result as is without any conversion. The conversion should only happen at other layer and not in the database layer.
It is okay to convert the result in this layer before returning.
Return the result as is without any conversion. The conversion should only happen at other layer and not in > the database layer.
In my view, repository layer should only do one thing. And this thing is to query database without applying any business logic and return result. Why? There are some reasones such as:
it complies with Single Responsibility Principle of SOLID principles.
code becomes simpler
code becomes more reusable
class will have lesser size
easier to write tests
So all conversions are made in service layer.
In addition, it is not good idea to return Dataset (with one or more tables) or DataTable from repository. It is better to return IEnumerable<T>. I mean you should avoid to return IQueryable or DataTable from repository to avoid querying at service layer. There are many opinions about this. So you can choose what is better for you. Should Repositories return IQueryable? imho, repository should not return IQueryable as all query logic should be placed in one place and not scattered across services.
More over, I hihly recommend you to read this post about is it better to return the most specific or most general type from an action method?
Generally speaking, your repository layer will return entities and it is your service layer that will repackage those into a form appropriate for your application to consume.
Note that what constitutes an entity may differ from project to project. For instance, if you use Entity Framework then it uses ADO.NET under the hood but it packages the data into entity classes and returns those objects. You could, in theory, do the same but, if you do, I'd question why you're not already using EF or some other ORM. If you're going to use ADO.NET directly then you probably ought to be returning DataTables and/or DataSets to your service layer. You should certainly not do some of one and some of the other. Go all in with one or the other.
Part of the idea behind a separate repository layer is that multiple different service layers should be able to be laid on top and work seamlessly, so the repository layer should be pretty general, based on the data rather than the application. Conversions are going to require business logic and that belongs in the service layer.
I was debating whether to post this as an answer or vote the question as too opinion-based but I think that the roles of the various layers are well-enough accepted that it's not really opinion any more.
Ideally your repository layer returns data mapped to Domain entitites/Domain types.
So the repository implementation would convert from low level db/ado specific types to your DTOs / Domain Types.
This way, you keep your domain clean and don't let those db specific types trickle into your business domain.
Related
I have read many posts concerning the issue of having several databases and how to design a DAL efficiently in this case. In many cases, the forum suggests to apply the repository pattern, which works fine in most cases.
However, I find myself in a different situation. I have 3 different databases: Oracle, OLE DB and SQLServer. Currently, there exists a unique DAL with many different classes sending SQL queries down to a layer below to be executed in the corresponding database. They way the system works is that two of the databases are only used to read information from them, and the other one is used to either store this same information or read it later on. I have to propose a better design to the current implementation, but it seems as if a common interface for all three databases is not plausible from an architectural point of view.
Is there any design pattern that solves this situation? Should I have three different DALs? Or perhaps it is possible (and advisable) to apply the repository pattern to this problem?
Answers to your question will probably be very subjective. These are some thoughts.
You could apply command-query separation. The query side integrates directly with your data layer, bypassing any business or domain layer, and the returning entities are optimized for read and project from your databases. This layer could also be responsible to merge results from different database calls.
The command side consists of command handlers, using domain or business entities, which are mapped from your R/W database.
By doing this, the interface that you expose will be more clear and business oriented.
I'm not sure that completely abstracting out the data access layer with custom units of work and repositories is really needed: do the advantages outweigh the disadvantages? They rarely do, because you will you ever change a database technology? And if you do, this probably means a rewrite anyway. Also, if you use entity framework code first, you already have unit of work and an abstraction on top of your database; and the flexibility of using LINQ.
Bottom line - try not to over-engineer/over-abstract things; or make things super-generic.
Your core/business code should never be dependent on any contract/interface/class that is placed in the DAL layer of the application.
Accessing data is something the business/core layer of your application needs to be able to do, and this it should be able to do without any dependency of SQL statements and without having any knowledge of the underlying data access technology.
I think you need to remove any "sql" statements from the core part of the application. SQL is vendor dependent and any dependency to a specific database engine needs to be clean out of you core, and moved to the DAL where it belongs. Then you need to create interfaces that resides outside of the DAL(s) which you then create implementation classes for in one or many DAL modules/classes. Your DAL can be dependent of your core, but not the other way around.
I don't see why the repository layer can't be used in this case. When I have a database which I can only read from, I usually let the name of the repository interface indicate this, like ICompanyRepositoryRead.
Recently I have been reading up on using the repository pattern and DI to help create easily testable code, I think I understand it for the most part. However I'm having difficulty with one issue. I need to create a Rules object for my applications business layer. To create a rule, I need the ability to read and write to two tables. How would you go about implementing a repository that uses two tables for one object?
for example:
ICollection<type> GetAllRules();
What would I put in for type as it requires two tables?
Thanks
Steve
I wouldn't insist on having a repository for that.
As Fowler says
Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer.
This is probably why most implementations tend to expose pure domain objects rather than derivatives (which your Rule object seems to be).
I would have two repositories for the two tables you mention, then I would have a unit of work to expose all repositories and then I would have a business layer service responsible for the compound processing.
An advantage of such approach would be that the repository layer remains clean, there is no business processing involved here, no unclear rules introduced to the persistence layer.
What is the best practice to return data objects from Data Access Layers to Interface?
Currently, I have a layer that communicates with database and returns DataTable to business Layer and then Business Layer instatiates the Business Objects and returns to the interface. Isn't that pathetic or poor practise?
My questions are:
-What is the best way to return Data Objects from DAL?
-If the DAL shouldn't return Data Objects, then how do I get the data to interface for DataBinding?
This is not a problem but a best practice issue.
Thanks everyone in advance
Have you looked at the Repository Pattern?
http://msdn.microsoft.com/en-us/library/ff649690.aspx
http://martinfowler.com/eaaCatalog/repository.html
I'm not sure that the DAL shouldn't return Data Objects - there are many personal preferences and it depends on factors such as the scale of the application. In the majority of the (smallish) applications I build, I used a datareader in the DAL rather than filling and passing around DataTables. The DAL uses the datareader to populate business objects that are then returned as a collection to the service layer.
In a more complicated scenario where tables don't always equate to business objects, I've used the datareader to populate DTOs (Data Transfer Objects - very simply classes that just contain variables representing the table structure and no logic) that are returned as a collection to the service layer. The Service Layer constructs the business objects from one or more types of DTO.
I'm not saying this is a definitive answer though (The problem with 'best practice' questions!) but hopefully my experience can give an insight (In what to do or what not to do is debatable!). I am interested myself to see what answers others can contribute to this. I suppose one answer you'll likely get is to investigate the use of an ORM!
I'm returning DataTable in DAL. And I have a businessObject called Customer. Where should I fill this object? Should it be done in DAL? Or in my front-end app? or where? A little cofused.
If at all possible, you want to avoid returning DataTable in your DAL and instead return the properly filled business object. There are several tools that will help you with this, for example LINQ to SQL, Entity Framework, or (my current favorite) Dapper.NET (used by this very site). I like Dapper best because it's lightweight and works well with a Data Repository pattern, which I frequently use.
You could have a Base DAL, which returns DataTables. Then have an Upper DAL, which does the converting to and from entities, (this is what I tend to use)
You really shouldn't be referring to DataTables in your UI layer.
A half-way house that I have seen before is doing the 'object filling' within a method in the actual business object itself, but that doesn't allow you to switch out your DAL so easily.
When crossing domains like this, where the representation of the data is different in each, you need an integration layer that will take care of the mapping between both representations. Most ORM tools do that mapping for you automatically, though.
But to stick with your example, you could have a layer of mappers to do that. CustomerMapper would then map from the DataTable to the Customer, effectively bridging the two domain representations.
It should be done in BL or Business Logic layer.
I'm working on a small application from scratch and using it to try to teach myself architecture and design concepts. It's a .NET 3.5, WPF application, and I'm using Sql Compact Edition as my data store.
I'm working on the business logic layer, and have just now begun to write the DAL. I'm just using SqlCeComamnds to send over simple queries and SqlCeResultSet to get at the results. I'm starting to design my Insert and Update methods, and here's the issue - I don't know the best way to get the necessary data from the BLL into the DAL. Do I pass in a generic collection? Do I have a massive parameter list with all the data for the database? Do I simply pass in the actual business object (thus tying my DAL to the conrete stuff in the BLL?).
I thought about using interfaces - simply passing IBusinessObjectA into the DAL, which provides the simplicity I'm looking for without tying me TOO tightly to current implementations. What do you guys think?
I don't think there is a simple answer to your questions because there are many options depending on the circumstances. I have found it helpful to read the two books below to help me understand the problems you describe better.
MS .NET: Architecting Applications for the Enterprise (Esposito, Saltarello)
MS Application Architecture Guide, 2nd edition.
The second book is available online. Look here.
I think it is OK to pass the Business object to the Data Access Layer. I think the BLL's job is just to work with its objects, to check if all rules are being followed, about what can be saved, by whom, on what fields, time, etc.
Once it has done that it should pass it to the DAL, and I think it is IT'S job to figure out how to convert what it got into something that can be persisted, but it wont check what is being persisted or read or by whom, it will just do it. This could be straight foward, a la linq, but if your logic mdoels do not match your data model 1:1, then the DAL should do all the conversion.
About tying your DAL to the stuff in the BLL, I think you should worry about the other way around, tying your BLL to your DAL. I would use an interface to represent your DAL (as in IRepository) that way you can make your BLL call any kind of persistance mechanism just by changing the type of IRepository it is using (extra points if you use IoC :P). The concrete classes that implement the IRepository would be tied to the business objects, but they have to know what is it that they are saving don't they? while the BLL does NOT have to know what is doing the saving.
To pass business object in the DAL is the simpler and fastest method. It works in small projects, but have same disadvantages:
1) Business Objects are part of BLL layer, and if you pass objects in BLL then DAL becomes dependent of BLL. low layer knows about upper one - this contradicts the idea of layers at all.
2) Business Object are usially very complex to save it directly in BD. In this case it is better to introduce new "Mappers" intermediate layer.
To overcome all these issues I usially make interface to DAL independent of Business Objects. I use "Row" classes instead - representation of one record in the database or XML. In .NET 3.5 linqtosql autogenerated classes can be used for this purpose.
If I was in your position, I'd probably use LINQ to SQL to define my data access layer - it'll save you lots of work maintaining all that SqlCeFooBar stuff and give you a designer (of sorts) for maintaining your database that you would otherwise lack, using SQL CE.
So in that case, I'd probably couple the business logic layer pretty tightly to the entities exposed by the L2S layer. The justification being that the entities are the business objects, albeit devoid of any services.
I probably wouldn't let the entities get as far up the hierarchy as the UI though. At that level, it makes much more sense to use a model specifically for the view - especially given that you're using WPF.
Of course, all of this depends upon the size and complexity of your application. I'm assuming it's a fairly small scale application (single user?) given that you're using SQL CE.