Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am a young developer who starts, I'm just learning Dependency injection and i have a question that torments me.
In my exemple I have a WCF service web (soap), it performs some simple business action and makes a call to the database.
So , my project is cut into
Service -> Business Layer -> Layer Data Access -> Data base
in my case, there is simple business action in business layer and à SELECT statment in data access layer .
So now (certainly wrong way) I used static class to communicate between my layers:
In summary :
Service Layer:
public void GetData()
{
BusinessLayer.GetData();
}
Business layer :
static class BusinessLayer
{
public static void GetData()
{
//If something or something else ...
DataAccessLayer.GetData();
}
}
Data Access Layer:
static class DataAccessLayer
{
public static void GetData()
{
//DO insert in database
}
}
First, is this a bad way to go?
Then, for this kind of very simple case, is that it is worthwhile to set up an IoC container?
Thank you in advance .
PS: Sorry for my English
I would make interfaces out of your layer classes. This removes the static classes, as desiried, and sets you up for injection. For your example, which is rather small, I would not recommend going through the trouble unless as a learning experience. There are no hard rules for when to use this injection but the pattern helps tremendously when unit testing comes about.
Nobody ever said: "Wow! This would have been much easier to write a unit test for if it were a static method or singleton!"
In the end you will have something along the lines of interface for the functionality you want to inject. This assumes some level of domain model will exist and raw data from the database will be converted into the model.
You would begin by defining the various interface you have to have injected into you dependent classes.
public interface IBusinessLayer
{
Data GetData();
}
public interface IDataAccessLayer
{
Data GetData();
}
public interface IDatabase
{
DbData GetDatabaseData();
}
The main goal is to have the container inject the funcitonality you to complete the operations desiried. In this, getting data. Assuming you data is a class in the domain model.
public class ServiceLayer
{
IBusinessLayer business = null;
public ServiceLayer(IBusinessLayer business)
{
this.business = business;
}
public void GetData()
{
Data data = business.GetData();
// do something with data
}
}
You can repeat the same pattern for the different layers. While this seems a lot of work for a simple application the hard edged given by the interfaces allow each layer to evolve on it own ... so long as the interface contract remains.
The segregation is nice if you keep the layers clearly defined. For example, by not letting raw database data, rows etc. bleed up into the upper layers.
public class BusinessLayer : IBusinessLayer
{
IDataAccessLayer dataAccess = null;
// container will inject data access layer
public BusinessLayer(IDataAccessLayer dataAccess)
{
this.dataAccess = dataAccess;
}
public Data GetData()
{
Data data = dataAccess.GetData();
// do something with data?
return data;
}
}
// Retruns typed data business layer
public class DataAccessLayer : IDataAccessLayer
{
IDatabase db = null;
public DataAccessLayer(IDatabase db)
{
this.db = db;
}
public Data GetData()
{
var db_data = db.GetDatabaseData();
Data data = /*convert raw db_data -> type domain data*/
return data;
}
}
Related
I am working on a web application that uses Angular 12 for the frontend and ASP.NET Core 6 for the backend. In our team we usually write just about anything as a 3-layer application (if possible) consisting of a presentation layer, a business logic layer and a data layer. In the case of this project, this would mean that when for example all entities of a certain type, let's call it Car, are requested from the server, the following would happen (simplified):
The request arrives in the CarController.cs controller. The carManager instance here belongs to the business layer and provides functions for interacting with car entities (CRUD for the most part). Dependency Injection is used to inject the carManager instance into the controller:
public async Task<ActionResult<List<Car>>> GetCars()
{
List<Car> cars = await this.carManager.GetCarsAsync();
return this.Ok(cars);
}
If there is anything business logic related, it will be done in the GetCarsAsync() function of the carManager. However, in many cases this is not necessary. Therefore, I often end up with "dumb" functions that just call the corresponding function of the data layer like this. The carAccessor in this example belongs to the data layer. Dependency Injection is also used here to inject its instance into the manager:
public async Task<ActionResult<List<Car>>> GetCarsAsync()
{
return this.carAccessor.GetCarsAsync();
}
The actual querying of the data is then done in the corresponding accessor for the entity. Example:
public async Task<List<Car>> GetCarsAsync()
{
List<Car> cars = new();
List<TblCar> dbCars = await this.Context.TblCars.ToListAsync();
foreach (TblCar dbCar in dbCars)
{
Car car = <AutoMapper instance>.Map<Car>(dbCar);
cars.Add(car);
}
return cars;
}
While this makes it easy to not mix up business logic and data access in the application, it really creates a whole lot of code that does nothing than just call other code. Therefore, in some cases the business layer is omitted simply because of laziness and business logic ends up just being implemented somewhere else, for example directly in the controller. Is there a simple solution for this?
Using generic base classes and inheritance could help you to reduce writing and maintaining of similar code everywhere for vanilla cases :
public abstract class BaseController<T, C>: Controller where T: class where C: IItemsManager<T>
{
protected C ItemManager { get; }
public virtual async Task<ActionResult<List<T>>> GetCars()
{
List<T> items = await this.ItemManager.GetItemsAsync();
return this.Ok(items);
}
}
public interface IItemsManager<T> where T : class
{
Task<List<T>> GetItemsAsync();
}
public class ItemsManager<T, B>: IItemsManager<T>
where T: class
where B: class
{
public virtual async Task<List<T>> GetItemsAsync()
{
List<T> items = new List<T>();
List<B> dbItems = await this.Context.Set<B>().ToListAsync();
foreach (B dbItem in dbItems)
{
T item = <AutoMapperinstance>.Map<T>(dbItem);
items.Add(item);
}
return items;
}
}
public class CarManager: ItemsManager<Car, TblCar>
{
}
public class CarController: BaseController<Car, CarManager>
{
}
The current solution I am working with is structured with a single Core layer that is connecting to the database whenever it needs to retrieve data.
I suggested to a few colleagues that we create a DAL layer and move all of the database logic into it's own project and call it
Application.DataAccess
This layer will use Entity Framework and the repository pattern as an abstraction between Application.Core and Application.DataAccess (The Repository implementation will sit within Application.DataAccess).
I plan to to consume the repository in a service layer.
public class JobService
{
private IJobRepository _jobRepository;
public JobService(IJobRepository repository)
{
_jobRepository = repository;
}
public IEnumerable<Job> GetJobs()
{
List<Jobs_AllJobs> allJobs = _jobRepository.GetAllJobs();
List<Job> result = new List<Job>();
foreach(job in allJobs)
{
result.Add(new Jobs() { Title = job.Title, OtherEntity = "Internal to the service"; });
}
return result;
}
}
Job Repository:
public class JobRepository : IRepository<Jobs_AllJobs>
{
DBContext _jobContext;
public List<Jobs_AllJobs> GetJobs()
{
return _jobContext.Jobs_AllJobs.ToList();
}
}
This is where it gets slightly heated between us.
I believe that the JobRepository should return a list of the database entity Jobs_AllJobs rather than manipulate the database entity and construct a new List of Job (This should be handled in the service layer). My colleagues believe that the manipulation should be done at the Repository level and that the JobRepository should pass back a List<Job> or IEnumerable<Job> rather than the database entity.
From my understanding the Repository pattern is meant abstract away the internal database implementation (Entity Framework/nHibernate/File System) and solely perform a CRUD operation upon database (Create, Retrieve, Update or Delete) and that the JobService should perform the manipulation and construct a new object and pass that back down to the consumer.
Which way would be correct? And which way follows the repository pattern the best?
I have
Public Class AuthorBLL : IAuthorBLL
{
Public Add_Author();
Public Get_AuthorsList();
}
Public Class BookBLL : IBookBLL
{
Public Add_Book();
Public Get_BookList();
}
Now I want to call my Business logic layer methods in my WCF layer and want to expose similar WCF OperationContracts methods to the UI.
My WCF class looks like this:
Public class WCFService : IWCFService
{
private IAuthorBLL _authorBLL;
private IBookBLL _BookBLL;
public WCFService(IAuthorBLL authorBll, IBookBLL bookBll)
{
_authorBLL = authorBll;
_bookBll = bookBll;
}
Public WCF_Add_Author (serializable_author author);
{
_authorBLL.Add_Author();
}
Public WCF_Get_AuthorsList()
{
_authorBLL.Get_AuthorList();
}
Public WCF_Add_Book (serializable_book book);
{
_bookBll.Add_Book();
}
Public WCF_Get_BookList()
{
_bookBll.Get_BookList();
}
}
Question:
My question is regarding the WCF constructor where i have to pass all these Business logic layer objects as constructor parameters to achieve DI. How can i make it generic so that if in the future I have publisherBLL, VentorBLL, CustomerBLL and so on... i don’t have to pass them all in the WCF constructor?
I know it’s the way dependency injection works but what if i have 50 BLL objects; will i have to pass them all in the WCF constructor. Is there any way to avoid it? Any design pattern or technique which can give me better solution to this.
I need to keep one WCF service which can expose all method whether its Authors, books, publishers, clients, customers or retailers. One service should expose all CRUD methods.
EDit:
As you are saying use Ninjet or CastleWinsor for IOC where you can create the containers to define DI. but still you have to define the constructor based parameters in the WCF constructor in WCF class.
Do we will have to define the constructor parameters as below. or if the WCF is too big to expose so many methods then what is a solution for an application where you have to do CRUD for Authors, books, employees (working in a shop), publishers, HR and payroll modules. every module have webpages and calling WCF service to do CRUD. as we never know when we will need to move on to Mobile interface or how many other applications will use the same methods so we want to expose all through WCF service. What should i do?
private IAuthorBLL _authorBLL;
private IBookBLL _BookBLL;
private IClientBll _ClientBll;
private IPublisherBll _PublisherBll;
private IHRBll _HRBll;
private IEmployeeBll _employeeBll;
public WCFService(IAuthorBLL authorBll, IBookBLL bookBll, IClientBll
clientBll, IPublisherBll publisherBll, IEmployeeBll
employeeBll, IHRBll HRBll)
{
_authorBLL = authorBll;
_bookBll = bookBll;
_authorBLL = authorBll;
_ClientBll = clientBll;
_PublisherBLL = publisherBll;
_HRBll = HrBll;
_EmployeeBLL = EmployeeBll;
}
As i have so many front end pages to deal with employees, authors, clients, books, publishers. What should i do.
You've pretty much answered yourself. If you use some DI framework like Unity or Ninject then you won't have to bother about passing 50 arguments to your constructor - just retrieve the service object from the DI framework's factory and it will care about providing appropriate arguments. Maybe what are you missing is that you can register your service in the DI framework along with it's dependencies.
Simple example with Unity:
In some kind of a Bootstrapper class which initializes whole application:
public void Run()
{
//...
SetupContainer();
//...
RunWebService();
//...
}
public void SetupContainer()
{
//This can also be done using a configuration file
this.container.RegisterType<IAuthorBLL, AuthorBLLImpl>();
this.container.RegisterType<IBookBLL, BookBLLImpl>();
this.container.RegisterType<IOther1BLL, Other1BLLImpl>();
//...
this.container.RegisterType<IOther50BLL, Other50BLLImpl>();
}
public void RunWebService()
{
this.container.RegisterType<IWCFService, WCFService>(
new ContainerControlledLifetimeManager());
var serviceSingleton = this.container.Resolve<IWCFService>();
//... proceed with service setup and run
}
Note that usually SetupContainer is split between different modules. Each of them registers its own classes.
I have a bank account domain as listed below. There can be SavingsAccount, LoanAccount, FixedAccount and so on. One user can have multiple accounts. I need to add a new functionality – get all accounts for a user. Where should be the function written and how?
It would be great if the solution follows SOLID principles( Open-Closed principle,…) and DDD.
Any refactoring that would make the code better is welcome.
Note: The AccountManipulator will be used by a website client over a web service.
namespace BankAccountBL
{
public class AccountManipulator
{
//Whether it should beprivate or public?
private IAccount acc;
public AccountManipulator(int accountNumber)
{
acc = AccountFactory.GetAccount(accountNumber);
}
public void FreezeAccount()
{
acc.Freeze();
}
}
public interface IAccount
{
void Freeze();
}
public class AccountFactory
{
public static IAccount GetAccount(int accountNumber)
{
return new SavingsAccount(accountNumber);
}
}
public class SavingsAccount : IAccount
{
public SavingsAccount(int accountNumber)
{
}
public void Freeze()
{
}
}
}
READING:
When to use the CQRS design pattern?
In domain-driven design, would it be a violation of DDD to put calls to other objects' repostiories in a domain object?
Refactoring domain logic that accesses repositories in a legacy system
Which of these examples represent correct use of DDD?
Good Domain Driven Design samples
Advantage of creating a generic repository vs. specific repository for each object?
if your AccountManipulator is a Façade to your domain, I wouldn't put the account number in the constructor. I would refactor it this way:
public class AccountManipulator
{
private AccountFactory _factory;
private UserRepository _users;
public AccountManipulator(AccountFactory factory, UserRepository users)
{
_factory = factory;
_users = users;
}
public void FreezeAccount(int accountNumber)
{
var acc = _factory.GetAccount(accountNumber);
acc.Freeze();
}
public IEnumerable<IAccount> GetAccountsOf(User user) {
return _users.GetAccountIds(user).Select(_factory.GetAccount);
}
}
public interface UserRepository {
IEnumerable<int> GetAccountIds(User user);
}
In order to state if your domain is SOLID, you should analyze it with the principle:
Single Responsibility: every object has is own responsibility (and only that one):
AccountFactory: creates IAccounts
SavingsAccount: implementation of IAccount that reads from/writes to (a database? a web service?)
AccountManipulator: provide a minimal and simple set of operations to do with domain objects.
Open/Closed: are you classes are open to extensions and closed to changes?
AccountFactory: well, no. If you write a new implementation of IAccount, in order to use it you have to change AccountFactory. Solution: abstract factory
SavingsAccount? It depends if it will use external dependencies. Need more code to say.
AccountManipulator: yes. If you need to do another operation with your domain objects, you can use directly the other services without change AccountManipulator. Or you can inherit from it
Liskov substitution: can you substitute any class with another implementation? Need more code to say. You have no other implementations of IAccount or IAccountFactory now
Dependency Inversion:
AccountManipulator should depend on abstractions: AccountFactory and UserRepository should be interfaces.
Firstly, to really answer your question it's important to know why you need to get all user accounts? Are you:
Fetching a list of accounts to display on screen for the user to
then perform a command/transaction against a single account?
Performing a single command/transaction on all of the users accounts - such as 'Freeze All User Accounts'?
The reason I ask is because you only need to consider the DDD aspect if it's the latter. If the reason for this 'functionality' is the former (and after reading your question I suspect it is) - I really recommend just creating a thin query service layer that gets the user's account data you need for the screen. You don't need to add the 'restrictions' of DDD for this; there are no transactions or model state changes involved. Providing this functionality doesn't have to involve the domain model at all. Just define some simple POCO DTO's and use Entity Framework to get the data and pass it back to the UI.
This is what CQRS is about; you don't need repositories, factories or aggregates to give the UI a list of accounts for the user to choose from - you would be over complicating it and making A LOT more work for yourself.
If there is a scenario that requires a single transaction over all of the user's accounts then I'd do something like:
public class AccountService : IAccountService
{
private IAccountRepository _accountRespository;
public void FreezeAllAccountsForUser(Guid userId)
{
IEnumerable<IAccount> accounts = _accountRespository.GetAccountsByUserId(userId);
using (IUnitOfWork unitOfWork = UnitOfWorkFactory.Create())
{
foreach (IAccount account in _accounts)
{
account.Freeze();
_accountRespository.Save(account);
}
}
}
}
Where AccountService is a webservice, i.e. the Application Layer.
In summary, my advice is: Only consider DDD in the context of commands that require transactions. For fetching lists of data; create a simple query service that the UI can consume.
P.S. I've noticed the misuse of the Factory pattern in your question and some of the answers. Factories are designed to provide an object's CREATION strategy, given particular data. There shouldn't be a 'GetAccount(accountId)' method that calls the database; repositories call the database then pass data to a factory to create the object.
First of all why do you need AccountManipulator? It does absolutely nothing, but makes the code more complicated.
As for getting all accounts of a User, the most logical place to put this method would be in the User class. You could pass an account factory to that method, further implementation would probably depend on how you store accounts.
I'd rename 'AccountFactory' to AccountRepository and put an extra method in it GetAccountsForUser( int userId ) which retrieves all Accounts for a specific user.
If AccountManipulator is a webservice, then this class will use the AccountRepository, like this:
public class AccountManipulator
{
public void FreezeAccount( int accountNr )
{
var repository = new AccountRepository();
var account = repository.GetAccount(accountNr);
account.Freeze();
repository.Save(account);
}
public ICollection<Account> GetAccountsForUser( int userId )
{
var repository = new AccountRepository();
return repository.GetAccountsForUser (userId);
}
}
I am new to design patterns and now I want to implement the Strategy patern. Here's my code:
namespace StrategyPattern
{
public interface ISendBehavior
{
void Send();
}
public class SendAppointment : ISendBehavior
{
public void Send()
{
// send item
}
}
public class SendTask : ISendBehavior
{
public void Send()
{
// send item
}
}
public class SendItem
{
ISendBehavior _sendBehavior;
public SendItem(ISendBehavior sendbehavior)
{
_sendBehavior = sendbehavior;
}
public void Send()
{
_sendBehavior.Send();
}
}
/* CALL */
public class Aanroep
{
public void Verzenden()
{
SendItem app = new SendItem(new SendAppointment());
app.Send();
}
}
}
In the method Send in the class SendAppointment the item will be send. My question is, do I have to connect to the database in this class? If so, then I also have to connect to the database in SendTask. But at this point I am repeating myself right? So if a connection string changes, i have to modify this in every class. How can I solve this problem?
You could have another layer of abstraction for the database operations. This layer should be responsible for taking all the database requests centralizing the access. Connections strings should be configured externally, and the data mapping layer could access them directly.
The Repository Pattern is a good pattern for this layer that you can apply. It can sit between your domain objects and the data mapping layers.
How about initializing each implementor of ISendBehavior with yet another object that's responsible for the database connection?
Your Verzenden()-implementation would be something like
IDatabaseConnection connection = new DatabaseConnection();
SendItem app = new SendItem( new SendAppointment( connection ) );
and your ISendBehavior.Send() would be implemented like this
_databaseConnection.Send( ... ); // fill behavior-specific information here (perhaps with properties)
This way, you can reuse that IDatabaseConnection for any other classes.
Since you don't like Lennaert answer of passing the connection to your class why not reverse it and create a connection class that uses a simple command pattern and pass your class to it as a the parameter?