Repository / services pattern and data consistency - c#

In a application that use Repositories and Services pattern, how to make sure Service layer is always called and not the Repositories directly ?
Example :
class OrderRepository
{
void CreateOrder(Order o)
...
}
class OrderService
{
void CreateOrder(Order o)
{
//make some business logic tests
...
//call repository
_orderRepository.CreateOrder(o);
}
}
I see two issues :
A programmer may call the repository directly because it doesn't know the existance of a service (sometimes its not as simple as in this example (1 service = 1 repository with same method names). some applications are not very well documented. or someone in hurry can forget to check if corresponding service exists (mistake)).
Totally different : long time ago someone created some views + controllers that use order repository directly. At that time there was no need to have some business logic check or additional operations, only order repository exists (because there it was not needed at all). If later, some additional operations when creating an order would be needed, a service will be created. the problem is that all controllers that make old repositories calls will need to be changed. Isn't repository principle/idea (and separating code in layers) supposed to make parts independent from each other ?

You can structure your solution so that all repositories and services are in their own respective projects, ex. Repositories and Services.
The only project that should reference Repositories would be Services. This way, other projects wouldn't have access to the repositories. Of course, nothing is to stop a developer from including the repositories project to the controllers project, but hopefully at this point they'll be asking themselves why it wasn't included in the first place.

Static analysis tools can help in this respect.
nDepend is a commercial tool that can be integrated into your build process and error on such a condition (any non service class calling a repository class directly).

Related

.Net Web API - Managers vs. Service vs Repository - where should my logic reside in?

I have some logic that performs operations on objects that are passed in. E.g.:
GetTotals(Item items){...} //Run through item props, sum them up
CombineItems(Item item1, Item item2){...} //Merge 1 into 2
Where should the simpler logic like this belong to, semantically? I won't be retrieving anything from the DB. Is it more likely to be a:
Service?
Manager?
Helper?
Something else?
PS. If Helper class or others, would it be common for it to be dependency-injected into the parent class calling it?
If those methods are static or they provide static logic to Item and it's shared by different callers, you could try make an extension method, so you could call them like
item1.CombineItems(item2, item3...);
Myself prefer extension method over static Helper because extension methods can be discovered by Intellisense.
There are also reasons you could make them into a service:
they are business logic
they need a lifetime, or need to be managed by DI container
they need to be mocked in unit tests
Depends on the project size / type and architecture. There could be multiple ways to organize it.
As a helper classes usually as a part of independent class library called SolutionName.Utils in a case classical N-tier monolith mostly for web apps.
As a part of Command / Query class logic in a case of DDD / CQRS based approaches.
As a simple method of class to which its related (usually it's for small apps)
Like extension method, on large projects it could be difficult to maintain.
As for DI, in classical monolith usually such things are not injected as they are independent from other parts of the logic and could be easily covered with unit tests.
If such logic blocks / or creates dependencies with other parts of the logic and therefore could not be fully covered with unit tests, than it means it needs to be injected.

Providing access to different data stores with the Repository Pattern

I've been trying to learn how the service layer and repository pattern work. So far I've written a service layer and a simple repository pattern interface. However, I often see articles stating that the repository pattern allows for being able to swap in and out different data stores without the consuming code having to be changed.
In my case I want to be able to support reading and writing the application data to CSV and/or XML files. This is the part where I do not understand how to properly implement this with the repository pattern. Should I have a repository per data store?
ProductCsvRepository : IProductRepository
ProductXmlRepository : IProductRepository
However if I do this then the service layer would have to be aware of the underlying data store, which breaks the idea of being able to easily swap in and out different data stores.
Would I then have to have a service layer that looks like this?
private readonly IProductXmlRepository _productXmlRepository;
private readonly IProductCsvRepository _productCsvRepository;
public ProductService()
{
_productXmlRepository = new IProductXmlRepository();
_productCsvRepository = new IProductCsvRepository();
}
public ICollection<Product> GetAllXml()
{
return _productXmlRepository.GetAllCsv();
}
public ICollection<Product> GetAll()
{
return _productCsvRepository.GetAllXml();
}
This then raises two questions:
Surely this then breaks the idea of the consuming code needing to know what the data store is?
What about in the situations where the consuming code does need to know about the data store, such as for "File > Export As" type functionality? Should export functionality actually be a different service that utilises the appropriate CSV or XML service?
I think I am definetly not understanding how to correctly implement a repository patten and a service layer. How should I actually design repository patten and service layer?
Take a look at dependency injection and the plug-in pattern. They support injecting a concrete implementation of a repository. Your service layer then has only one reference to IProductRepository and a concrete repository gets injected. Something along the lines of this:
public class ProductService
{
private readonly IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
}
public class ConsumingClass {
{
private readonly IProductService _productService = new ProductService(new ProductXmlRepository());
// methods to use the the product service
}
But better would be to use a inversion of control container like NInject or SimpleInjector. Those frameworks can be used to link abstract classes (IProductRepository) to concrete classes (ProductXmlRepository or ProductXmlRepository) based on xml configurations.
Your application's solution should be structured following the Dependency Inversion Principle (http://deviq.com/dependency-inversion-principle/), so that there are at minimum three projects:
Core
Infrastructure
Your UI project
All (or nearly all) of your interfaces should be declared in Core (e.g. IProductRepository). Your interface implementations belong in Infrastructure, which references Core. Finally, your UI project should reference Core, but not necessarily Infrastructure (learn how to use types from a project without referencing it: http://blog.falafel.com/use-types-from-project-without-referencing/).
With this architecture in place, you can use dependency injection (http://deviq.com/dependency-injection/) to inject the desired implementation of a given type at runtime, which provides great flexibility and testability.
Setting up your solution with the proper dependencies between projects is critical to being successful with this approach, since a traditional UI -> Business Layer -> Data Layer setup will not allow you to invert dependencies. Once your solution is set up in this manner, you should follow the Explicit Dependencies Principle (http://deviq.com/explicit-dependencies-principle/) in all of your UI and service code.

Accessing common functions across multiple services

I'm currently building an application, and as it stands I have a single service for each controller (the service handles the business logic for the controller). Each service has it's own dbcontext.
I've recognised that several services need to perform the same functions (retrieve the same lists of data from the database and perform the same logic on them before returning them). So ideally I need a way for the services to access common functions.
My first thought is to create a simple helper class that each service could use, with simple functions that take a dbcontext as one of the parameters, so that the functions could perform database queries as well as logic and return the result.
Is this a good idea? Would I run into problems by structuring my code this way, or is there a better more robust and accepted approach I should take?
I'd say you're on the right track, but go one step further with the single responsibility principle. http://blog.codinghorror.com/curlys-law-do-one-thing/. It's a proven strategy for keeping code clean. I avoid "helper" classes per say. They can get messy by having too many responsibilities. Instead I try to really think about what my class should do. Then I give it a really good name to remind me that it only does that one thing.
The fact that your services each have their own Db Context can be a problem. Just make sure that if you call upon more than 1 dependent service that you pass in the same Db context to them all. If your object graph is large, a container like AutoFac will be a big help.
Is the data being returned the same? Are they using their own unique DB context or is it the same DB context?
Generally I would recommend avoiding creating a helper class. Generally a helper class is used to manipulate an object(s) rather than perform a database query.
Based on your comment there are two ways you could achieve this, one easier than the other.
Option 1:
If your application really is a simple one that you're not too concerned about doing things the 'correct' way then you could simply create base service class and update your services to extend it, and move your common database access into the base class, like so:
abstract class BaseService
{
...
public ICollection<ExampleRecord> GetDatabaseRecords()
{
using (var context = new ApplicationDbContext())
{
/* Your DbContext code */
}
return databaseRecords;
}
...
}
Then extend BaseService like so:
public class ExampleService : BaseService
{
...
public ICollection<ExampleRecord> GetRecords()
{
return this.GetDatabaseRecords();
}
...
}
This would get the job done and be a better option to what you're currently doing, however it's generally not the best approach.
Optios 2:
If your application is more than a simple one and you're concerned about code maintainability then I would suggest looking into moving your database access code into a separate repository class and use an IoC container such as StructureMap to inject it the said repository into your services via dependency injection.
Personally I would recommend option 2 as it's far cleaner, more maintainable/extensible and you're not violating any of the SOLID principles.
You can use an abstract service to define a common methods
This is a good tutorial about
generic repository, services layer, IoC, unit test an entity framework

Session and Transaction managment in Service Layer

I have an application that will have some presentations layer (web, mobile, wpf, wcf, windows service to work on background etc...) and We are using NHibernate to persist the domain objects. We will have repositories (class library) to persist data, a service layer to use theses repositories to persist according to business rules. My question is, we do not know how to implement the a trasactional management in this service layer. We will probably use (more than one) repositories in a same service layer method and we need to control the transaction on the service layer. I would like to implement something like this (by attributes):
public class DomainObjectService
{
[Transactional]
public bool CreateDomainObject(DomainObject domainObject, /* other parameters */)
{
foreach(var item in /* collection */)
{
_itemRepository.Save(item);
}
if (/* some condition */) {
/* change the domainObject here */
}
_domainObjectRepository.Save(domainObject);
}
}
And does this Transactional attribute control my transactional with Commit/RollBack when we got erros. Is it possible? Or is there another solution to do this?
Thank you
What you have asked does not have a straight forward answer.
The behavior you wish to have sounds like you need to implement a unit of work pattern.
NHibernate's own ISession is in fact an implementation of a unit of work. I personally recommend implementing your own unit of work so that you have greater control over what your specific application considers a unit of work.
The use of attributes in a service layer class really doesn't make a lot of sense to me personally. I have seen people create custom controller attributes in an MVC application that handles transactions but I've never personally agreed with that kind of implementation.
You mentioned using more than one repository in the service layer. This is quite a common practice but it also means that each of those repositories will need to be operating within the same unit of work. If you application is using dependency injection, then one option is to have each repository accept an ISession in its constructor. Your dependency injection framework of choice could be setup in such a way as to inject the same ISession into all of the repositories. Your setup could be configured to begin a new transaction every time a new ISession is created.
You also mentioned different presentation layers such as web, mobile, wpf, etc. How you deal with sessions and transactions in each of those different types of applications can be quite different. That is why I always point people in the unit of work direction because each of those different application types could have a completely different definition for what it considers a unit of work. For a web application, you would typically go with a new unit of work for each web request. For a wpf application, the unit of work could be per screen, or until the user hits the save button, etc. Also, by implementing a unit of work, you can reuse that same unit of work implementation more easily across those different application types.
Again, this is not a question wish a straight forward answer but in general, I typically make use of a custom unit of work and a dependency injection framework to make this problem much easier to deal with.
Here are some helpful links that you may wish to investigate:
http://nhibernate.info/doc/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.html
Correct use of the NHibernate Unit Of Work pattern and Ninject
Unit of work/repository managers for NHibernate?

httpcontext extension and IOC considerations

Hi created an extension method to control the lifecycle of an EF context. My code is below
public static Entities GetCentralRepositoryContext(this HttpContext httpcontext)
{
if (HttpContext.Current.Items["context"] == null)
{
HttpContext.Current.Items["context"] = new Entities();
}
return (Entities)HttpContext.Current.Items["context"];
}
I've created many layers in my solution as projects and have started to think about IOC. The above code sits in my BL layer project but for it to work I need to create a reference to my DL layer as that's where the entities class resides. How can I remove the reference to my DL layer and inject into my extension method. Is this even possible?
The approach you are taking has several problems. First of all, static methods tend to be a problem for loose coupling, and you'll notice this quickly when trying to unit test your code. Besides this, your business layer has a dependency on System.Web, which makes your business layer technology specific, which will make it very hard to move part of the system to for instance a Windows Service, and again makes unit testing almost impossible.
Instead of doing this, start injecting your Entities class into the constructor of all types that need it. At the beginning of each request you can build up the dependency graph of services in your application, specific to that request. At that point you can determine that the Entities instance should have a lifetime of a web request.
This however, will start to get cumbersome to do without a DI framework. Or at least, a DI framework will make this much easier to do.
When you start writing unit tests, you'll find that it will be very hard when directly using the EF ObjectContext in your application. This article might give you some ideas how to abstract the ObjectContext behind a testable interface.

Categories

Resources