I am reading up about service layers and repositories. Now I am wondering if a service layer must wrap the dal. I am working a lot with repositories and the MVP pattern. The presenters now holds the business logic. But the more I think about it, it is not a logic place to put the business logic in the presenter nor the data access layer. So this is the point the service layer comes in.
But does the presenter now talks to the service layer? And is it 'allowed' that the presenter can access the repositories? Or should everything go via the service layer? In the latter case, the service layer is just a middleman:
MyFooService:
public List<Foo> GetAllFoo()
{
var listFoo = new FooRepository().GetAll().TiList();
return listFoo;
}
Presenter:
public List<Foo> GetAllFoo()
{
var listFoo = new MyFooService().GetAllFoo();
return listFoo;
}
Is the good way to go? Or is it 'allowed' that the presenter directly calls the repository?
Sometimes you do not need to over engineer things or force into patterns when you don't need them.
The DAL, is itself sorta a special service to access data.
Typically your service layer will do stuff not related directly to your data. Think things like PaymentService, AnalyticsService etc things like that, that can be separated into a re-usable component.
Lets say you needed to share a post on to all social media, you could put this into a service that does the job of signing into the right social media and posting:
MySocialBlastService : ISocialService
{
void ShareToTwitter() { }
void ShareToFacebook(){ }
}
Now from your controller/presenter you can call this service.
public ActionResult ShareLink(string link..) //asp.net-mvc method as an example
{// maybe you could use dependency injection here to get ISocialService
ISocialService _service;
_service.ShareToTwitter(link);
}
Just so you're clear on what business logic is:
MathService
{
int Add(a,b) { ..} //this is business logic
}
Its some stuff you need to do, and you can do it without touching an interface, this needs to be encapsulated. More real world examples are SecurityService.ResetPassword()
When you call this from the controller:
You could use the business logic of adding in a web app, or in a windows app, and get the inputs from the user through some interface. How you do that is controller logic.
public ActionResult Calculate(int a, int b)//comes from webpage
{
//this is controller logic
int ret = MathService.Add(a,b);
//logic to send ret back
//to some other page to display to user.
}
I would say that if you are doing "serious" middle to big scale development it is better not to put business logic into your presentation layer. How you isolate it is another question.
On the other side if you use something like Entity Framework or NHibernate I would only create repositories if it is really necessary to abstract data access, for using mocks when testing, for example.
Related
I am creating an application and I am using Façade design pattern, in which request will go through
Controller (webApi) -> Façade -> Business -> Repository
And I am using Unity config to initialize my objects (façade, business, and repository), in the controller layer I will set Unity config and initialize all objects. But my doubt is how I can pass repository object to business layer.
Like I am using repository methods call in business layer and it will definitely require repository object so I injected that in business layer constructor. See below code:
public class MessageBusiness : IMessageBusiness
{
IMessageRepository _messageRepository;
public MessageBusiness(IMessageRepository messageRepository)
{
_messageRepository = messageRepository;
}
public int AddMessage(RS.DomainEntity.Model.Message newMessage)
{
return _messageRepository.AddMessage(newMessage);
}
}
Now should I pass this repository object from Façade layer?
public class MessageFacade : IMessageFacade
{
IMessageBusiness _messageBusiness;
public MessageFacade(IMessageBusiness messageBusiness)
{
_messageBusiness = messageBusiness;
}
public int AddMessage(RS.DomainEntity.Model.Message newMessage)
{
return _messageBusiness.AddMessage(newMessage);
}
}
If not then I can I inject this repository in my business layer? OR if YES then we will need to pass this in Façade as well, it’s like passing object from one layer to another. Is that the right behavior?
Also If you give the ans for first question then how can I perform integration testing in my Façade layer. Any idea? Any help is much appreciated. Thanks in advance.
Regards,
Vivek
Now should I pass this repository object from Façade layer?
Not really, you don't have to. In such straightforward graph like yours, you only need a unity controller factory and facades injected into controllers. Unity will do the rest, to initialize a facade it will go for a business service and since it needs a repository, Unity will find and inject one, assuming of course you register all interfaces to implementations in advance.
Btw. I definitely recommend Unit of Work instead of Repository. UoW is more general and allows the client to access all possible repositories. You can think of it like of a container to all repositories.
I am working on asp.net mvc5 web application and I am using entity Framework as the data access layer. Whenever I start implementing new requirement , I always get stuck on how I should design the interaction between action methods and repository classes. . for example let say I have the following Post Create action method:-
Public ActionResult CreateStudent (Student student)
{
repository.AddStudent(student);
repository.Save();
return RedirectToAction(“Index”);
}
And here is the repository
Public class Repository {
Public Void AddStudent (Student student)
{
// + Initiate a pending Audit Object
//+ Create new Person object and retrieve its ID
SaveChanges();
//+ create new Student and assign it to the created Person
// + Complete Audit object
}
This is how I currently implement the interactions, less calls from action method to repository, and i have somehow large repository methods.
But as another approach I can have more calls to the repository methods, and have smaller repository methods comparing to the first approach such as:-
Public ActionResult CreateStudent (Student student)
{
var audit = repository.IntiateAudit(student);
var person = repository.AddPerson(student);
repository.Save();
var student2 = repository.AddStudent(person);
repository.CompleteAudit(audit);
repository.Save();
return RedirectToAction(“Index”);
}
And here is the repository
Public class Repository {
Public Audit IntiateAudit(Student student)
{
//implementation goes here…
Return Audit;
}
Public Person AddPerson (Student student)
{//implementation goes here…
Return Person
}
Public Student AddStudent (Person person)
{//implementation goes here…
Return student;
}
so generally speaking which approach is considered better;either having smaller repository methods and multiple calls , OR large repository methods with less calls to the repository methods ?
I wouldn't put those individual repository calls in the controller as you generally shouldn't really be responsible for the implementation details of creating a student there.
I would have the controller implement a Student Service and have a CreateStudent method on the service. The service would implement the repository(s) or context(s) it needs to deal with orchestrating the logic needed.
If you have a service you can encapsulate logic which spans repositories and hide the details from the controller which should not act as the model.
Services are easily reusable - e.g. maybe later you'll add an API layer to your app which can also create students. You don't want to replicate code to do that.
Accessors.
You could also create a data accessor layer which would hide the repositories and UoW.
Actually I went through building an MVC 4 portal where I put everything inside the MVC application, for example my business logic in the controllers, my data access in the model, and my presentation layer in the view.
This approach would be suitable for small projects where you don't have that much business logic and a small data model, using this pattern you would put all the calls inside the controller and areas section, you would have helper classes to do some business logic, the model will hold only data definitions, and the view will list the data.
A new approach which I love more and I work toward in my new systems is to deal with the MVC application as a presentation layer, where the controller will do the needed preparation and format to send the data(model) to the view to be presented.
In this case you need a new BLL (class library or a service) which will hold all your business, and DAL (class library or service) to hold all your data access work.
In this case the MVC application will do minimal calls to the BLL to get whatever data/logic processing, and the BLL will do the same if it needs to get some data from the DAL.
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. :)
I have a real scenario that is a perfect Domain Model design.
It is a field that has multiple quadrants with different states on every quadrant.
So my aggregate root is the field.
Now i have one important question:
I want to have a persitant ignorat domain model, which i think makes sense. so where should i call the update on the repository methods? not in the domain model, right?
So how should the aggregate root child entities update in the database when there is no change tracking proxy of this objects and the repository should not be called in the entities?
Or do i misunderstand the domain model pattern?
is my question clear? :)
thank you in advance
best
laurin
So where should i call the update on the repository methods?
In a stereotypical DDD architecture the repository is usually called by an application service. An application service is a class which serves as a facade encapsulating your domain and implements domain uses cases by orchestrating domain objects, repositories and other services.
I'm not familiar with your domain, but suppose there is a use case which shifts a State from one Quadrant in a Field to another. As you stated, the Field is the AR. So you'd have a FieldApplicationService referencing a FieldRepository:
public class FieldApplicationService
{
readonly FieldRepository fieldRepository;
public void ShiftFieldState(int fieldId, string quadrant, string state)
{
// retrieve the Field AR
var field = this.fieldRepository.Get(fieldId);
if (field == null)
throw new Exception();
// invoke behavior on the Field AR.
field.ShiftState(quadrant, state);
// commit changes.
this.fieldRepository.Update(field);
}
}
The application service is itself very thin. It does not implement any domain logic; it only orchestrates and sets the stage for execution of domain logic which includes accessing the repository. All code dependant of your domain, such as the presentation layer or a service will invoke domain functionality through this application service.
The repository could be implemented in a variety of ways. It can be with an ORM such as NHibernate, in which case change tracking is built in and the usual approach is to commit all changes instead of calling an explicit update. NHibernate provides a Unit of Work as well allowing changes to multiple entities can be committed as one.
In your case, as you stated, there is no change tracking so an explicit call to update is needed and it is up to the repository implementation to handle this. If using SQL Server as the database, the Update method on the repository can simply send all properties of a Field to a stored procedure which will update the tables as needed.
The Aggregate Root (AR) is updated somwehere. Using a message driven architecture, that somewhere is a command handler, but let's say for general purpose that is a service. THe service gets the AR from a repository, calls the relevant methods then saves the AR back to repository.
The AR doesn't know about the repository, it is not its concern. The Repository then saves all the AR modficications as a unit of work (that is all or nothing). How the Repo does that, well, that depends on how you decided your persistence strategy.
If you're using Event Sourcing, then the AR generates events and the Repo will use those events to persist AR state. If you take a more common approach, that AR should have a state data somewhere exposed as a property perhaps. It's called the memento pattern. The repository persist that data in one commit.
Bu one thing is certain: NEVER think of the persistence details, when dealing with a Domain object. That is don't couple the Domain to an ORM or to some db specific stuff.
The "application code" should call the repository. How the application code is hosted is an infrastructure concern. Some examples of how the application code might be hosted are WCF service, as a Winforms/WPF application, or on a Web server.
The repository implementation is responsible for tracking changes to the aggregate root and its child entities as well as saving them back to the db.
Here is an example:
Domain Project
public DomainObject : AggregateRootBase //Implements IAggregateRoot
{
public void DoSomething() { }
}
public IDomainObjectRepository : IRepository<DomainObject>, IEnumerable
{
DomainObject this[object id] { get; set; }
void Add(DomainObject do);
void Remove(DomainObject do);
int IndexOf(DomainObject do);
object IDof(DomainObject do);
IEnumerator<DomainObject> GetEnumerator();
}
Implementation Project
public SqlDomainObjectRepository : List<DomainObjectDataModel>, IDomainObjectRepository
{
//TODO: Implement all of the members for IDomainObjectRepository
}
Application Project
public class MyApp
{
IDomainObjectRepository repository = //TODO: Initialize a concrete SqlDomainObjectRepository that loads what we need.
DomainObject do = repository[0]; //Get the one (or set) that we're working with.
do.DoSomething(); //Call some business logic that changes the state of the aggregate root.
repository[repository.IDof(do)] = do; //Save the domain object with all changes back to the db.
}
If you need to transactionalize changes to multiple aggregate roots so the changes are made on an all or nothing basis, then you should look into the Unit of Work pattern.
Hope this helps clarify things!
My solution is the aggregate root will raise some events to event handlers outside. Those event handlers will call repository to update the database. You will also need a ServiceBus to register and dispatch events. See my example:
public class Field: AggregateRoot
{
public UpdateField()
{
// do some business
// and trigger FieldUpdatedEvent with necessary parameters
....
// you can update some quadrants
// and trigger QuadrantsUpdatedEvent with necessary parameters
}
}
public class FieldEventHandlers: EventHandler
{
void Handle (FieldUpdatedEvent e)
{
repository.Update(e.Field);
}
}
public class QuadrantEventHandlers: EventHandler
{
void Handle (QuadrantsUpdatedEvent e)
{
repository.Update(e.Quadrant);
}
}
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
}
}