Where to put the method. Service layer ( BL ) over repository? - c#

I'm confused about one thing. I've used a repository pattern (not generic) in my previous mvc apps and I used to include some kind of business logic there. At this moment I read about service layer pattern where should be included BL. But now I don't know if there is more abstraction and extra code instead of cleary/readable and efficient code.
I want to implement a method like this
public void ChangeActiveField(bool isActive, int id)
{
var objectToUpdate = _context.FirstOrDefault(x=>x.id==id);
objectToUpdate.IsActive - isActive;
_context.Entry(objectToUpdate).State = System.Data.Entity.EntityState.Modified;
_context.Save();
}
In this code there is a bit of business logic where I change state of one field and after that I update this.
Should I make it in service layer and then use simple repository update method liek this: ?
public class MyService
{
private readonly IMyRepository = _myRepo;
MyService(IMyRepository myRepo) //it's injectable
{
_myRepo = myRepo;
}
public void ChangeActiveField(bool isActive, int id)
{
var myObject = _myRepo.GetMyObject(id);
myObject.IsActive = isActive;
_myRepo.Update(myObject);
}
}
Is it better aproach? Does it make better separation? Or it's too sophisticated and overwrite?
Thank you for your help.
Best regards.

In general repository should encapsulate only the logic of accessing database (initialization of context, transactions, connections and etc.). It is very common to create a generic CRUD repository and reuse it for all your business entities.
All the business related logic should be placed in business layer(service layer).
The major benefits of this approach are:
Testability - you can test your business logic without relying on concrete repository implementation by injecting fake repositories(stubs).
Decoupling - neither your business layer nor your UI are not coupled to specific database, If tomorrow you will decide to migrate your database for example from SQL server to Redis(NoSQL database), your changes will be contained on repository layer only.
Maintainability - there is a clear separation of concerns for each layer: UI - interaction with user, BL - implementation of business logic, Repository - interaction with DB.
In my experience having a business layer (no matter how simple it is at the beginning - it's often grows up together with your project) is always a good idea.
By the way some developers consider repository as an unnecessary layer of abstraction in case that you use EF (in a way EF database context is a repository...).
One thing I've learned, is that the major effort is not a development phase of a project it is it's maintenance and upgrades - and here having a business layer a significant impact.
Disclaimer: It is my subjective opinion based on my experience

Related

Unit of Work through tiers

I'm refactoring an existing MVC.Net application to include the unit of work pattern to make data management a bit more obvious and straight forward.
The application is currently split into
Presentation/UI (MVC Controllers delivering views OR JsonResults for AngularJS)
Business Logic (Containing well... business logic)
DAL (Repositories and EF)
I'm having a hard time trying to figure out how I need to be structuring dependency injection and UoW passing to keep things sensible and testable.
I'm anticipating something like the following to be an example:
public class SomeMVCController : Controller
{
private readonly IStoreFrontLogic _storeFrontLogic;
public SomeMVCController(IStoreFrontLogic storeFrontLogic)
{
_storeFrontLogic = storeFrontLogic;
var uow = new UnitOfWork(User);
_storeFrontLogic.UnitOfWork = uow;
}
public ActionResult SomeRequest()
{
var myViewModel = _storeFrontLogic.OffersForUser();
return View(myViewModel);
}
}
public class StoreFrontLogic : IStoreFrontLogic
{
public UnitOfWork unitOfWork;
public OffersModel OffersForUser()
{
//some logic taking into account the current user in the uow
var prevOrders = unitOfWork.OrdersRepo.GetUsersOrders();
// special offers logic
return specialOffers;
}
}
Does this seem sensible?
I'm not too keen on the requirement to manually push the uow into my logic classes whenever they're required. Is there a more sensible way?
As I said above, this is hard to answer without a specific question or specific domain model but I'll give it a shot.
My understanding of such things is focused pretty heavily through a Domain Driven Design lens.
First of, you should read this series of papers on effective aggregate design. The fact that you need units of work and to do queries from inside your domain classes implies that your model needs work.
Some other thoughts on UOW - having uow produce your repositories is good, but I think you will likely start hitting lots of difficulties with implementation. UoW is super useful in small targeted areas but is very difficult to implement across an entire application. What for example happens when you save? Can you never use EF directly? Is everything thread safe? You might want to simplify what you are trying to achieve.
In your example uow can be scoped to the HttpRequest. Many IoC containers (eg Structuremap) provide a simple way to configure this. You can then have a post-action filter (or even better an OWIN module) to attempt the commit (what happens if there are errors is yet another implementation difficulty to deal with). This will eliminate a lot of the property-assignment nonsense
I'm not sure what type of object is your StoreFrontLogic. It doesn't seem like a domain entity but it contains significant business logic. It could be something similar to a transaction script, but in that case the uow should be fully internal to it.
Is it a stateless service? In that case everything that method uses - orders for user included - should be passed in via a parameter.
If, on the other hand it's an entity then it shouldn't access the database at all, it should already have all orders for the user. Purposeful database denormalization can help quite a bit here.
At the very least pass uow as a parameter to OffersForUser rather than expecting for a property to be set.

Design issue with interaction between Service Layer and DAL Layer

I have a design problem with my poject that I don't know how to fix, I have a DAL Layer which holds Repositories and a Service Layer which holds "Processors". The role of processors is to provide access to DAL data and perform some validation and formatting logic.
My domain objects all have a reference to at least one object from the Service Layer (to retrieve the values of their properties from the repositories). However I face two cyclical dependencies. The first "cyclical dependency" comes from my design since I want my DAL to return domain objects - I mean that it is conceptual - and the second comes from my code.
A domain object is always dependent of at least one Service Object
The domain object retrieves his properties from the repositories by calling methods on the service
The methods of the service call the DAL
However - and there is the problem - when the DAL has finished his job, he has to return domain objects. But to create these objects he has to inject the required Service Object dependencies (As these dependencies are required by domain objects).
Therefore, my DAL Repositories have dependencies on Service Object.
And this results in a very clear cyclical dependency. I am confused about how I should handle this situation. Lastly I was thinking about letting my DAL return DTOs but it doesn't seem to be compatible with the onion architecture. Because the DTOs are defined in the Infrastructure, but the Core and the Service Layer should not know about Infrastucture.
Also, I'm not excited about changing the return types of all the methods of my repositories since I have hundreds of lines of code...
I would appreciate any kind of help, thanks !
UPDATE
Here is my code to make the situation more clear :
My Object (In the Core):
public class MyComplexClass1
{
MyComplexClass1 Property1 {get; set;}
MyComplexClass2 Property2 {get; set;}
private readonly IService MyService {get; set;}
public MyComplexClass1(IService MyService)
{
this.MyService = MyService;
this.Property1 = MyService.GetMyComplexClassList1();
.....
}
This is my Service Interface (In the Core)
public interface IService
{
MyComplexClass1 GetMyComplexClassList1();
...
}
This my Repository Interface (In the Core)
public interface IRepoComplexClass1
{
MyComplexClass1 GetMyComplexClassObject()
...
}
Now the Service Layer implements IService, and the DAL Layer Implements IRepoComplexClass1.
But my point is that in my repo, I need to construct my Domain Object
This is the Infrascruture Layer
using Core;
public Repo : IRepoComplexClass1
{
MyComplexClass1 GetMyComplexClassList1()
{
//Retrieve all the stuff...
//... And now it's time to convert the DTOs to Domain Objects
//I need to write
//DomainObject.Property1 = new MyComplexClass1(ID, Service);
//So my Repository has a dependency with my service and my service has a dependency with my repository, (Because my Service Methods, make use of the Repository). Then, Ninject is completely messed up.
}
I hope it's clearer now.
First of all, typically architectural guidance like the Onion Architecture and Domain Driven Design (DDD) do not fit all cases when designing a system. In fact, using these techniques is discouraged unless the domain has significant complexity to warrant the cost. So, the domain you are modelling is complex enough that it will not fit into a more simple pattern.
IMHO, both the Onion Architecture and DDD try to achieve the same thing. Namely, the ability to have a programmable (and perhaps easily portable) domain for complex logic that is devoid of all other concerns. That is why in Onion, for example, application, infrastructure, configuration and persistence concerns are at the edges.
So, in summary, the domain is just code. It can then utilize those cool design patterns to solve the complex problems at hand without worrying about anything else.
I really like the Onion articles because the picture of concentric barriers is different to the idea of a layered architecture.
In a layered architecture, it is easy to think vertically, up and down, through the layers. For example, you have a service on top which speaks the outside world (through DTOs or ViewModels), then the service calls the business logic, finally, the business logic calls down to some persistence layer to keep the state of the system.
However, the Onion Architecture describes a different way to think about it. You may still have a service at the top, but this is an application service. For example, a Controller in ASP.NET MVC knows about HTTP, application configuration settings and security sessions. But the job of the controller isn't just to defer work to lower (smarter) layers. The job is to as quickly as possible map from the application side to the domain side. So simply speaking, the Controller calls into the domain asking for a piece of complex logic to be executed, gets the result back, and then persists. The Controller is the glue that is holding things together (not the domain).
So, the domain is the centre of the business domain. And nothing else.
This is why some complain about ORM tools that need attributes on the domain entities. We want our domain completely clean of all concerns other than the problem at hand. So, plain old objects.
So, the domain does not speak directly to application services or repositories. In fact, nothing that the domain calls speaks to these things. The domain is the core, and therefore, the end of the execution stack.
So, for a very simple code example (adapted from the OP):
Repository:
// it is only infrastructure if it doesn't know about specific types directly
public Repository<T>
{
public T Find(int id)
{
// resolve the entity
return default(T);
}
}
Domain Entity:
public class MyComplexClass1
{
MyComplexClass1 Property1 {get; } // requred because cannot be set from outside
MyComplexClass2 Property2 {get; set;}
private readonly IService MyService {get; set;}
// no dependency injection frameworks!
public MyComplexClass1(MyComplexClass1 property1)
{
// actually using the constructor to define the required properties
// MyComplexClass1 is required and MyComplexClass2 is optional
this.Property1 = property1;
.....
}
public ComplexCalculationResult CrazyComplexCalculation(MyComplexClass3 complexity)
{
var theAnswer = 42;
return new ComplexCalculationResult(theAnswer);
}
}
Controller (Application Service):
public class TheController : Controller
{
private readonly IRepository<MyComplexClass1> complexClassRepository;
private readonly IRepository<ComplexResult> complexResultRepository;
// this can use IoC if needed, no probs
public TheController(IRepository<MyComplexClass1> complexClassRepository, IRepository<ComplexResult> complexResultRepository)
{
this.complexClassRepository = complexClassRepository;
this.complexResultRepository = complexResultRepository;
}
// I know about HTTP
public void Post(int id, int value)
{
var entity = this.complexClassRepository.Find(id);
var complex3 = new MyComplexClass3(value);
var result = entity.CrazyComplexCalculation(complex3);
this.complexResultRepository.Save(result);
}
}
Now, very quickly you will be thinking, "Woah, that Controller is doing too much". For example, how about if we need 50 values to construct MyComplexClass3. This is where the Onion Architecture is brilliant. There is a design pattern for that called Factory or Builder and without the constraints of application concerns or persistence concerns, you can implement it easily. So, you refactor into the domain these patterns (and they become your domain services).
In summary, nothing the domain calls knows about application or persistence concerns. It is the end, the core of the system.
Hope this makes sense, I wrote a little bit more than I intended. :)

Mocking NHibernate & Linq

I'm using NHibernate and exposed the Session in my front end. I have a controller action which retrieves tasks as follows:
public ActionResult Overview(DateTime date)
{
var allTasks = GetTasksUpUntilDate(date);
return PartialView("Tasks/Overview", allTasks);
}
private List<TaskOverviewModel> GetTasksUpUntilDate(DateTime date)
{
var allTasks = _session.Query<Task>().Where(t.BookedBy.UserName.Equals(CurrentUser.Name,
StringComparison.CurrentCultureIgnoreCase));
var tasks = allTasks.Where(t => t.DueDate <= date);
var taskVMs = new List<TaskOverviewModel>();
tasks.ForEach(t => taskVMs.Add(MapEntityToViewModel(t)));
return taskVMs;
}
Now I don't want to create an IRepository just for my views since ISession actually already is a repository. Mocking/stubbing this however is proving rather hard. So can anyone help me to have _session.Query return a list of objects I provide while testing?.
I'd also like to avoid setting up an in memory database and am using RhinoMocks for my tests.
Dont fake Nh/linq. Instead setup an in-memory sqlite db to query against. They are extremely fast and easy to use.
NHibernate Session might fit the repository pattern, but if you are building your controllers to talk to it directly, you are not truly abstracting it. Mocking it when you aren't abstracting it is not a reliable solution.
If you absolutely don't want to abstract it (which is pure lazy, IMO), then the sqllite db as mentioned by Jason is a good call. However, on a large project properly separating your concerns is very much a good idea.
My domain model contains the interfaces for both the data access objects (repos) and the services which consume them. This allows me to truly separate my data concerns from my business concerns, which should be entirely separated from the view/app concerns. This allows proper unit testing and the ability to easily swap out parts or do proper mocking.
Each layer ONLY talks to interfaces, NEVER to an implementation. Furthermore my application layer never talks directly to the data layer - only services. Allowing that to happen seems to encourage developers to be lazy and start putting business or data logic into the application.

Repository pattern and/or/vs business logic layer

I have a problem I want to know your opinion.
I am trying to use Repository Pattern. I have a repository object which load data to a POCO. I have also created a Business logic layer which adds a little bit of functionality but basically wraps the POCO. So in the end I have a BLL which loads DAO with usage of repository.
I am not very happy with this solution. I have a three layers but I feel that BLL is not providing enought functionality to keep it there. On the other hand I do not want to put my logic in the repository layer nor data access layer?
So my question is where should I put logic for application? Which solution do you use(DAO + repo or DAO + BLL + rep or any other)?
There are two basic ways to think about business rules when designing your domain.
1.) The domain entities are basic POCO/DTOs. And you hand them off to domain services. These services could be as simple as another class, or they really could be actual services sitting on another server.
var user = repository.Find(x => x.UserName == userName);
if (userLogonService.IsValidUser(user, password)) {
userLogonService.UpdateUserAsLoggedOn(user);
}
repository.SaveChanges();
2.) The domain entities contain their own operation logic. This is closer to what many MVC patterns will follow. And since you asked, this is the model that I prefer.
var user = repository.Find(x => x.UserName == userName);
if (user.CheckPassword(password)) {
user.LogOnNow();
}
repository.SaveChanges();
Both are completely valid patterns. #1 has a discrete business operation tier, but suffers from an Anemic Domain Model. #2 can lead to big domain entities if you domain starts to become complicated, or if a model can do a lot of things.
EDIT #1: Response to John Kraft
Oven.Bake(myPizza) vs. myPizza.Bake()
I mostly agree. Do you have a single Oven service, or do you have dozens of available ovens stored in an oven repository where oven is just another domain entity? In #2, the oven is part of the domain. The way I tend to do domain modeling, most nouns are domain entities, unless you are 100% sure that there is exactly one of the thing.
But something does happen to pizza when it is baked.
interface ICanBeBaked {
int BakeMinutes { get; }
int BakeTemp { get; }
void Bake();
}
class Pizza : ICanBeBaked {
int BakeMinutes { get { return 15; } }
int BakeTemp { get { return 425; } }
void Bake() {
// melt cheese!
this.isBaked = true;
}
}
class Oven {
void Bake(ICanBeBaked thingToBake) {
// set the temp, reserve this oven for the duration, etc.
thingToBake.Bake();
}
}
My "DAL" (more of a home-grown ORM, which is another topic) is really a couple of layers in itself; one abstraction that provides repository and some active record pattern support, and below that is the actual data access code.
We have a minimal business layer at this point, but the real reason is that it's thin is that there's way too much (legacy) business logic embedded in web page code-behinds. As that gets refactored, I expect the business layer to grow and grow and grow.
This is fairly standard layering. You don't say why you're unhappy with your current stack, but keep in mind that the core reason for doing this is separation of responsibilities. You might also want to take a look at concepts of Domain Driven Design; it provides lots of food for thought for organizing code around business policies and practices, rather than specifically software issues. It's a very useful analytical tool to have in your toolbox.

Save Me on a Business Object

I've commonly seen examples like this on business objects:
public void Save()
{
if(this.id > 0)
{
ThingyRepository.UpdateThingy(this);
}
else
{
int id = 0;
ThingyRepository.AddThingy(this, out id);
this.id = id;
}
}
So why here, on the business object? This seems like contextual or data related more so than business logic.
For example, a consumer of this object might go through something like this...
...Get form values from a web app...
Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
thingy.Save();
Or, something like this for an update...
... Get form values from a web app...
Thingy thingy = Thingy.GetThingyByID(Int32.Parse(Form["id"].Value));
Thingy.Name = Form["name"].Value;
Thingy.Save();
So why is this? Why not contain actual business logic such as calculations, business specific rules, etc., and avoid retrieval/persistence?
Using this approach, the code might look like this:
... Get form values from a web app...
Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
ThingyRepository.AddThingy(ref thingy, out id);
Or, something like this for an update...
... get form values from a web app ...
Thingy thingy = ThingyRepository.GetThingyByID(Int32.Parse(Form["id"].Value));
thingy.Name = Form["Name"].Value;
ThingyRepository.UpdateThingy(ref thingy);
In both of these examples, the consumer, who knows best what is being done to the object, calls the repository and either requests an ADD or an UPDATE. The object remains DUMB in that context, but still provides it's core business logic as pertains to itself, not how it is retrieved or persisted.
In short, I am not seeing the benefit of consolidating the GET and SAVE methods within the business object itself.
Should I just stop complaining and conform, or am I missing something?
This leads into the Active Record pattern (see P of EAA p. 160).
Personally I am not a fan. Tightly coupling business objects and persistence mechanisms so that changing the persistence mechanism requires a change in the business object? Mixing data layer with domain layer? Violating the single responsibility principle? If my business object is Account then I have the instance method Account.Save but to find an account I have the static method Account.Find? Yucky.
That said, it has its uses. For small projects with objects that directly conform to the database schema and have simple domain logic and aren't concerned with ease of testing, refactoring, dependency injection, open/closed, separation of concerns, etc., it can be a fine choice.
Your domain objects should have no reference to persistance concerns.
Create a repository interface in the domain that will represent a persistance service, and implement it outside the domain (you can implement it in a separate assembly).
This way your aggregate root doesn't need to reference the repository (since it's an aggregate root, it should already have everyting it needs), and it will be free of any dependency or persistance concern. Hence easier to test, and domain focused.
While I have no understanding of DDD, it makes sense to have 1 method (which will do UPSERT. Insert if record doesn't exist, Update otherwise).
User of the class can act dumb and call Save on an existing record and Update on a new record.
Having one point of action is much clearer.
EDIT: The decision of whether to do an INSERT or UPDATE is better left to the repository. User can call Repository.Save(....), which can result in a new record (if record is not already in DB) or an update.
If you don't like their approach make your own. Personally Save() instance methods on business objects smell really good to me. One less class name I need to remember. However, I don't have a problem with a factory save but I don't see why it would be so difficult to have both. IE
class myObject
{
public Save()
{
myObjFactory.Save(this);
}
}
...
class myObjectFactory
{
public void Save(myObject obj)
{
// Upsert myObject
}
}

Categories

Resources