In the following example, the AccountService and ProductService are in an ASP.NET MVC app. The AccountWebAPI and ProductWebAPI are externally hosted API micro services.
1) Can I eliminate the ProductService and orchestrate the retrieving of the orders in the CustomerAccountController itself? This is because I consider the Controller as the Application layer/service which is mentioned in the DDD (Domain Driven Design).
2) Am I violating the n-layer architecture because the ProductService calls the AccountService which is the same layer?
3) Since AccountWebAPI and ProductWebAPI are micro services, do they have to be separated as AccountService and ProductService in the client application (MVC App) also to keep the Separation Of Responsibility? So the ProductService needs to be renamed as ProductAppService and ProductService should interact with ProductWebAPI only like AccountService talks to AccountWebAPI.
public class CustomerAccountController : Controller
{
IProductService _productService;
public CustomerAccountController(IProductService productService)
{
_productService = productService;
}
public IActionResult Index()
{
return View();
}
public IActionResult Account(int customerId)
{
var orders = _productService.GetOrders(customerId);
return View(orders);
}
}
public class ProductService
{
IAccountService _accountService;
IProductWebAPI _productWebAPI;
ProductService(IAccountService accountService, IProductWebAPI productWebAPI)
{
_accountService = accountService;
_productWebAPI = productWebAPI;
}
IList<Order> GetOrders(int customerId)
{
// Find the International Customer Number for CustomerId
object customer = _accountService.GetInternationCustomerInfo(customerId);
// Convert the string type to int
var modifiedCustomerNumber = Convert.ToInt32(customer.Id);
// Get the orders
return _productWebAPI.GetOrders(modifiedCustomerNumber);
}
}
public class AccountService
{
IAccountWebService _accountWebAPI;
CustomerService(IAccountWebService accountWebAPI)
{
_accountWebAPI = accountWebAPI;
}
object GetInternationCustomerInfo(int customerId)
{
return accountWebAPI.GetCustomer(customerId)
}
}
UPDATE: I realized that OrderService would be the appropriate service name for orders and not ProductService.
The LAYERS:
VIEW -- CONTROLLER -- SERVICE -- WebAPIs -- DOMAIN -- REPOSITORY
OrderView -- CustomerAccountController -- ProductService (calls AccountService in the same layer) -- ProductWebAPI -- ProductDomain -- ProductRepository
The names AccountService and ProductService imply that you are violating the Single Responsibility Principle, Open Closed Principle and Interface Segregation Principle. Together, those three principles are 60% of the SOLID principles.
The reasoning for this is explained in this article, but in short:
The Single Responsibility Principle is violated, because the methods in each class are not highly cohesive. The only thing that relates those methods is the fact that they belong to the same concept or entity.
The design violates the Open/Closed Principle, because almost every time [a method] is added to the system, an existing interface and its implementations need to be changed. Every interface has at least two implementations: one real implementation and one test implementation.
The Interface Segregation Principle is violated, because the interfaces [such as IProductService] are wide (have many methods) and consumers of those interfaces are forced to depend on methods that they don’t use.
The solution is to give each use case its own class. This design is explained in detail here and here.
I would even say that having Web API controllers with the same structure leads to the same kind of SOLID violation. In fact, if you apply the design given by the articles, you can completely remove all your Web API controllers, and replace them with a single piece of infrastructure logic that will be able to pass messages around. Such design is described here (the article mainly talks about WCF, but its applicable to Web API as well and a working example of Web API can be seen in the example project that the article links to).
1) Can I eliminate the ProductService and orchestrate the retrieving of the orders in the CustomerAccountController itself?
You could do that, but that means you would mix up delivery logic with applicative logic. It's not the worst SRP violation but that would remove the option of adding a second delivery mechanism (something else than Web API) for the same use case. It can be a valid tradeoff in some circumstances though.
2) Am I violating the n-layer architecture because the ProductService calls the AccountService which is the same layer?
Absolutely not. An architecture is a set of constraining technical decisions that were made. The only way you could violate an architecture would be to set up a second, parallel architecture that somehow breaks principles from the original one. Here, you wouldn't even violate the n-layer approach since nothing in it says that you shouldn't call someone in the same layer.
3) Since AccountWebAPI and ProductWebAPI are micro services, do they have to be separated as AccountService and ProductService in the client application (MVC App) also to keep the Separation Of Responsibility? So the ProductService needs to be renamed as ProductAppService and ProductService should interact with ProductWebAPI only like AccountService talks to AccountWebAPI.
Your question suggests that the use of microservices might not be a thought out, educated choice here. Microservices are separation of responsibility taken to the extreme. They should be independently deployable and share as few things as possible. I also suggest you model your subdomains and Bounded Contexts (big business areas) first. Microservices will naturally fall into one of the BCs.
Related
Im new in MVC pattern but im involved in a project which i am asked to implement repository pattern and unit of work,tons of examples online with 100 different implementations thats also a pain,because there is no clear way,any way,here is what i am doing and i would like you to give me a reason why should i use this damn pattern:
i have many controllers i instantiate the the model,and use it in my controller:
public CentralEntities DB = new CentralEntities();
i use it in my controller for example like this:
var turbineid = (from s in DB.MasterDatas
where s.name == turbinename
select new TrBineId
{
turbineID = s.m_turbine_id
}).Single();
TrBineId is my viewModel,any way the number of controllers are increasing and also in each controller i have many different LINQ,should i start with generic repository?
The damn reason to use repository pattern lies in implementing your solution with a clear separation of concerns and leverage domain I/O in a way that can be reused across your codebase.
You should start to revisit OOP and you'll need to double-check repository pattern.
At the end of the day, the need for certain patterns is already there, but it'll arise in your mind once you put the pieces in order.
I would start following some tutorial around the net about repository pattern to implement a proof-of-concept project and realize how it works.
Finally, Inversion of Control and Dependency Injection are concepts you'll need to manage to integrate your repositories and other patterns in your project to increase code composability and testability.
DISCLAMER: The following links are from my website about software architecture. You might want to check them as a possible reference implementation of repository pattern:
Repository
Agnostic repository
The repository pattern allows you to use the concept of Single responsibility principle, which mean (as an overview) one class = one role.
Your controler class is here for managing the request (Get, Post) and send back a response (FileResult, ActionResult...).
For the Data access (DAL, DAO) you will usually create a class per model entity (ClientRepository, CommandRepository), and you will create your methods for getting them (GetClients(), GetOneClientById(int id)...) within this class.
Edit for clarification after Matías comment:
This class will be called in your controller through his interface that you will also implement (with IOC or not).
You will then create a class instance of ClientRepository in your controller, but assigned to a reference of the interface type (IClientRepository).
**End Edit **
So we can imagin for Client Entity:
ClientController(All route for clients data)
IClientRepository (interface)
ClientRepository (Class which implement IClientRepository )
Then, in your controller you will call the repository like
IClientRepository clientRepo = new ClientRepository();
And then use the methods:
ICollection<Client> clients = clientRepo.YourMethod(int param1);
Advantages:
First of all, your code will be more clear and maintainable. Your DAO (DAL in .net) will keep the data access layer and you could use the GetAllClients method many time and you will not repeat yourself (DRY).
You can also apply easily some param on the method (like order, limit for pagination etc...)
It will be testable as well, I don't think that calling database in the controller can give you reasonable unit test results. You will also catch excption with a more "elegant way".
Small tip : When you will have more experience in the repo pattern, you could have a look at the Inversion of Control pattern
Numerous business logic services within my program need access to a common set of non-business logic services, such as email, printing, messaging (message boxes and prompts), and logging. I am planning on creating a facade to encapsulate EmailService, PrintService, MessageService, and LogService so that each business logic service just needs one constructor parameter to the facade class, instead of four parameters to each of the services.
So instead of
public BusinessLogicService(IEmailService emailService, IPrintService printService, IMessageService messageService, ILogService logService)
{
this.EmailService = emailService;
this.LogService = logService;
this.MessageService = messageService;
this.PrintService = printService;
}
I'll have this
public BusinessLogicService(ISomeFacade facade)
{
this.SomeFacade = facade;
}
My questions are:
Is this the correct usage of the facade pattern? If not, how should I be doing this?
I assume that having a standard set of services that are needed by a lot of business services is pretty common, so is there a standard naming convention for this sort of facade that encapsulates EmailService, PrintingService, MessagingService, LoggingService, and possibly some other non-business logic services that I need in the future?
What you've described is not facade but rather service locator (see for discussion on that pattern - Is ServiceLocator an anti-pattern?). Note that trouble coming up with the name is very good sign of creating IKitchenSink interface.
To be facade it must somehow simplify interaction with the services - maybe have one ArchveMessage call that will orchestrate working with all 4 services.
Number of constructor parameters generally does not matter* since one likely will be creating such objects with dependency injection framework anyway. Using DI framework may also take care of most "logging" responsibility by providing a way to log start/end/error cases for all method calls.
*) large number of injected dependencies indicate too many responsibilities of the class and need to be looked at from that point of view.
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. :)
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
We normally use abstract function/Interfaces in our projects. Why it is really needed? Why can't we just go for Business logic Layer, Data Access Layer and Presentation Layer only
Function in Presentation Layer:
abc();
Function in Business Logic Layer:
public void abc()
{
//Preparing the list
}
Function in Data Access Layer:
public abstract void abc();
Function in Data Access SQLServer Layer:
public override void abc()
{
//Connection with database
}
Question is: Why is the Data Access Layer required ?
The easiest way to understand this, imo, is an abstraction over DataLayer.
You have set a functions to retrieve a data from xml file. But one day your product scales out and xml is not enough like a data storage. So you pass to some embeded database: sqlite. But one day you need to reuse your library in some enterprise context. So now you need to develop access to sqlserver, oracle, webservice.... In all these changes you will need to change not only the code that actually access the data, but the code that actually consumes it too. And what about the code that already use for years your first xml data access on client and happy with it? How about backcompatibility?
Having the abstraction if not direcly solves most of this problems, but definitely makes scallable your application and more resistant to changes, that, in our world, happen sometimes too frequently.
Generally, if you use interfaces in your code, then you will gain code manuverability in the form of Dependency Injection.
This will help you replace parts of your implementation in certain situations for example providing Mock objects during Unit Testing.
The abstract class or interface is not really a separate layer - it should be part of your business logic layer and it defines the interface that the actual data access layer (SQL data repository, for example) needs to implement to provide the data access service to your business layer.
Without this interface your business layer would be directly dependent on the SQL layer, while the interface removes this dependency: You put the abstract class or the interface into the business logic layer. Then the SQL layer (a separate assembly, for example) implements the abstract class/interface. This way the SQL layer is dependent on the business layer, not the other way around.
The result is a flexible app with an independent business layer that can work with multiple data repositories - all it needs is a layer that implements the interface the business layer defines. And it is not really only about data repositories - your business layer shouldn't be dependent on the context (asp.net vs. console app vs. service etc.), it shouldn't be dependent on the user interface classes, modules interfacing with your business app, etc.
Why interfaces :
Have you ever used using in c# :
using (Form f = new Form())
{
}
Here you will see that you can use only those classes inside using which implements IDisposable interface .
Two things which does not know each other can interact with each other using Interfaces only.
Interface gurantees that "some" functionality has surely been implemented by this type.
Why layers :
So that you can have separate dlls which will let you to reuse in different application.
Basically all is for code reuse and Performance gain.
I think you are talking about Facade layer.
It is an optional layer which will simplify the functions of Business Layer. Let's imagine, you have a ProductManager and CategoryManager and you want to do a particular action which involves using both (for example, get me top 5 products in all categories) then you could use a facade layer that uses ProductManager and CategoryManager.
It is inspired by Facade Pattern.
The abstraction helps create functionality, be it through a base class, an interface, or composition which, when used properly, does wonders for maintenance, readability, and reusability of code.
In regards to the code posted in the question, the code marked "Data Access Layer" acts as a common abstraction for the business layer to use. By doing so, the specific implementations of the the DAL (such as what's under "Data Access SQLServer Layer" in the sample) are decoupled from the business layer. Now you can make implementations of the DAL that access different databases, or perhaps automatically feed data for testing, etc.
The repository pattern is a fantastic example of this at work in a DAL (example is simplified):
public interface IProductRepository
{
Product Get(int id);
...
}
public class SqlProductRepository : IProductRepository
{
public Product Get(int id) { ... }
...
}
public class MockProductRepository : IProductRepository
{
private IDictionary<int, Product> _products = new Dictionary<int, Product>()
{
{ 1, new Product() { Name = "MyItem" } }
};
public Product Get(int id) { return _products[id]; }
...
}
public class AwesomeBusinessLogic
{
private IProductRepository _repository;
public AwesomeBusinessLogic(IProductRepository repository)
{
_repository = repository;
}
public Product GetOneProduct()
{
return _repository.GetProduct(1);
}
}
Even though this example uses interfaces, the same applies to the use of base classes. The beauty is that now I can feed either SqlProductRepository or MockProductRepository into AwesomeBusinessLogic and not have to change anything about AwesomeBusinessLogic. If another case comes along, all that's needed is a new implementation of IProductRepository and AwesomeBusinessLogic will still handle it without change because it only accesses the repository through the interface.
All of the previous answers may explain the needs of abstract layers, but I still want to add some of my thoughts.
Let's say that in our project we just have one implementation of a service in each layer. For instance, I have a contact DAL and a contact BLL service , and we could do something like this
namespace Stackoverflow
{
public class ContactDbService
{
public Contact GetContactByID(Guid contactID)
{
//Fetch a contact from DB
}
}
}
Contact BLL service:
namespace Stackoverflow
{
public class ContactBLLService
{
private ContactDbService _dbService;
public ContactBLLService()
{
_dbService = new ContactDbService();
}
public bool CheckValidContact(Guid contactID)
{
var contact = _dbService.GetContactByID(contactID);
return contact.Age > 50;
}
}
}
without defining interfaces/ abstract classes.
If we do like that, there would be some obvious drawbacks.
Code communication:
Imagine that if your project involves, your services may have many different methods, how could a maintainer (apart from you) know what your services do? Will he have to read your entire service in order to fix a small bug like InvalidCastOperation?
By looking at the interface, people will have the immediate knowledge of the capabilities of the service(at least).
Unit testing
You could test your logic using a fake/mock service to detect bugs in advance as well as prevent regression bugs from happening later.
Easier to change:
By referencing only by interfaces/ abstract classes in other classes, you could easily replace those interface implementations later without too many efforts of work.
Abstraction enables you to do refactoring quickly. Think of instead of using SQL server, you decide to use some other provider; if you do not have a data access layer, then you to do a huge refactor because you are calling data access methods directly. But if you have a data access layer, you only write a new data access layer, inheriting from your abstract data access layer and you do not change anything in the business layer.
I am near the end of a new ASP.NET MVC application I have been developing, and I have realised that I am not 100% on what should be goning on in my controller methods.
Is it better for an action method to decide which services/methods are called and in what order like so:
AccountService _accountService;
BillingService _billingService;
InvoiceService _invoiceService;
...
public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
{
_accountService.UpgradeAccountPackage(packageType, accountId);
_billingService.BillForAccountUpgrade(packageType, accountId);
_invoiceService.CreateAccountUpgradeInvoice(packageType, accountId);
}
Or is it better to stick to a single method call to one service and allow this method to call the other services/support method it needs?
public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
{
// account service upgrades account then calls the BillingService and InvoicService
// methods called above within this method
_accountService.UpgradeAccountPackage(packageType, accountId);
}
I have tended to go for the second example here, as it seemed originally like the first method would constitute logic in some way, and means the acion method would have to intrinsically know about how the account upgrade process works within my application, which seems like a bad thing.
However, now my application is almost finished it has a large service layer and this approach has led to almost every service having a strong dependency on numerous other services, and there is no centralised place which decides the flow of business transactions such as the one mentioned above, you have to dig around a bit in service methods to discover the processes.
I am considering refactoring to more closesly resemble the second method above, or introducing a new layer in between the controller and service layer which controls the flow of processes.
Do people tend to use the first or second method? What are peoples opinions?
I prefer the second method - much easier to test (using mocks), and the logic is there for reuse. You end up with Facades to your actual business logic, but that's not bad thing.
I don't understand why your service layer is full of concrete dependencies though...
The thing to remember is that you want classes to rely on interfaces, not implementation. (and then string it all together with a Dependancy Injection tool)
In C#, we can have one class implement many interfaces. So your service implementations can implement many interface, and yet the caller need only know about the part they need.
For example, you might have an AccountTransactionService that imlpements IDepositor and IWithdrawer. If you implement double-entry accounting, then that could depend on IDepositor and IWithdrawer, which, in actual fact, just uses the same instance of AccountTransactionService, but it doesn't have to, and the implementation details could be changed afterwards.
In general, the less one class knows about the other classes in the system, the better.
I more closely use the first method. Let the controller control what happens. Let the services decide how that happens.
If you add a second layer to control the flow of processes would that leave your ActionMethods only making the one call? If so, it seems unnecessary at that point.
You could have a service layer which depends on multiple repositories (not other services) and which defines the business operations:
public class MyService: IMyService
{
private readonly IAccountRepository _accountRepository;
private readonly IInvoiceRepository _invoiceRepository;
private readonly IBillingRepository _billingRepository;
public MyService(IAccountRepository accountRepository, IInvoiceRepository invoiceRepository, IBillingRepository billingRepository)
{
_accountRepository = accountRepository;
_invoiceRepository = invoiceRepository;
_billingRepository = billingRepository;
}
public void UpgradeAccountPackage(PackageType packageType, int accountId)
{
...
}
}
and then have your controller take IMyService as dependency:
public class HomeController: Controller
{
private readonly IMyService _service;
public HomeController(IMyService service)
{
_service = service;
}
public ActionResult UpgradeAccountPackage(PackageType packageType, int accountId)
{
_service.UpgradeAccountPackage(packageType, accountId);
...
}
}
I define simple CRUD operations with the entities on the repositories and the service aggregates those multiple operations into one business transaction.