You work on a legacy app which has a static class UserDataAccess:
public static class UserDataAccess
{
public static void AddUser(User user)
{
// Insert user into DB
}
}
which is used by a UserService class:
public class UserService
{
public bool AddUser(string firstName, string lastName)
{
User user = ...
UserDataAccess.AddUser(user);
}
}
You need to add unit tests for the UserService class, but you cannot modify the UserDataAccess (you are not allowed, you do not have access to the DB).
A good solution is to create an interface and inject into UserService:
public interface IUserDataAccess {
void AddUser(User user);
}
and add an implementation which delegates the call to the static class:
public class UserDataAccessProxyOrAdapter : IUserDataAccess
{
public void AddUser(User user) {
UserDataAccess.AddUser(user);
}
}
My question is, is this a Proxy or an Adapter?
Proxy is supposed to add some functionality. Can the access to the static resource be considered a functionality?
It looks like an Adapter because it adapts the UserDataAccess to be called through the IUserDataAccess interface
What is the correct reasoning and why?
EDIT: This is from this refactoring test, specifically at this step: https://youtu.be/U3QvTaw224o?t=944
This is neither an Adapter nor a Proxy design pattern.
Adapter can be dismissed easily because an Adapter's API differs from the API of the object it adapts. Both IUserDataAccess and UserDataAccess share the same API: AddUser(User user), which rules out the Adapter pattern.
Proxy can be dismissed for the reason mentioned in the OP: there is nothing more than a direct passthrough from UserDataAccessProxyOrAdapter to UserDataAccess. No remote call, no deferral of instantiation cost, no access control, no additional action taken at all.
We would not want to call this simple example a Proxy design pattern, because that would imply every composition is a Proxy, which would devalue the pattern entirely.
But, do note that proxy is also a general English word; so while it doesn't make sense to name this example a Proxy design pattern, calling it a proxy based on the broader dictionary definition could be valid. I'm not sure whether that was the author's intent or not.
Related
I have a three layered architecture.
I can't use constructor injection and I need to get access to a service in my business code, in which I don't have access to HttpContext.
For example, in action methods, or in filters or middleware I can get a service using:
HttpContext.RequestServices.GetRequiredService<ITranslator>();
But in my business code, I don't have access to HttpContext.
How can I get an instance of my service?
Update:
Here's my business code:
public class InvoiceBusiness
{
// for some reasons, I can't use constructor injection here
public void CalculateTranslationsInvoice(long customerId)
{
// I need to get an instance of ITranslator here, and a couple of other services.
// If this method was in a controller, I could use HttpContext.RequestServices.
// But here what should I do?
}
}
If you're needing to access HTTP concerns in the inner layers, you should abstract it to an interface.
Assume you need to access the current user. Normally, you'd use HttpContext.User. But you can't access it in the domain layer.
The solution is to define an interface in your domain layer that encapsulates what your ITranslator implementation actually needs from the HTTP context.
public interface IUserAccessor {
ClaimsPrincipal CurrentUser { get; }
}
public class Translator: ITranslator {
// inject the interface
private readonly IUserAccessor _userAccessor;
public Translator(IUserAccessor userAccessor) {
_userAccessor = userAccessor;
}
// ...
}
Keep this interface as focused as possible. Here, I'm OK with using ClaimsPrincipal and having a dependency on the standard library, but if you're not, you can just extract the user id claim if that makes sense in your application.
Then implement this interface in the application/HTTP layer.
internal class HttpUserAccessor: IUserAccessor {
IHttpContextAccessor _httpAccessor;
public HttpUserAccessor(IHttpContextAccessor httpAccessor) {
_httpAccessor = httpAccessor;
}
public ClaimsPrincipal CurrentUser => _httpAccessor.HttpContext?.User;
}
Then register this implementation:
services.AddHttpContextAccessor();
services.AddScoped<IUserAccessor, HttpUserAccessor>();
Now you can access HTTP concerns in any layer without that layer knowing where the data actually comes from.
The bottom line is: you don't have to forego dependency injection. You can define & implement interfaces in different layers.
I have a scenario where I need to get an implementation not known until runtime.
My approach so far is by creating a service class (to abstract the logic from the classes that use them).
The clients and the service is registered with DI. The calling classes only requests Service.
Below are two different approaches (simplified):
public class Service
{
private readonly IClient client1;
private readonly IClient client2;
public Service(Client1 client1, Client2 client2)
{
this.client1 = client1;
this.client2 = client2;
}
public Data GetData(string client, string something)
{
if (client == "client1")
return this.client1.GetData(something);
return this.client2.GetData(something);
}
}
And:
public class Service
{
private readonly IServiceProvider serviceProvider;
public Service(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public Data GetData(string client, string something)
{
if (client == "client1")
return this.serviceProvider.GetRequiredService<Client1>().GetData(something);
return this.serviceProvider.GetRequiredService<Client2>().GetData(something);
}
}
And then this is used by calling:
service.GetData("client1", ...)
Are any of these alternatives a good approach for doing this? Is one preferable over the other?
In all cases, option 2 is a bad one.
The service locator pattern is widely considered to be an antipattern. It may solve the problem at hand but it creates many other problems down the line.
You're letting your consumer decide which client to use, which effectively negates the idea of letting the service define its own dependency using the constructor.
Magic strings are never desirable. If your consumer is deciding the client anyway, then it makes no sense for them to have to use some magic string to select the correct client. It's considerably less error prone to let them pass the client itself - but then Service isn't relying on the DI framework for the client object, which may defeat the purpose of your setup.
IF the choice of client is made dynamically every time GetData() is called, then option 1 is a valid approach.
Though I would suggest using more descriptive names than "client1" and "client2" where possible.
IF the choice of client is dynamic, but remains fixed after application start, meaning that all calls to GetData() during the same runtime will be handled by the same client, then it's better to choose this client when registering your dependencies:
// Startup.cs
if( /* selection criteria */)
{
services.AddScoped<IClient, Client1>();
}
else
{
services.AddScoped<IClient, Client2>();
}
// Service.cs
public class Service
{
private readonly IClient client;
public Service(IClient client)
{
this.client = client;
}
public Data GetData(string something)
{
return this.client.GetData(something);
}
}
Though I would suggest using more descriptive names than "client1" and "client2" where possible.
Note that your selection criteria can be whatever you want them to be, e.g. an app config value, database value, environment value, compilation type (debug/release), ... The world is your oyster.
Also evaluate whether you'd be better off implementing an additional abstraction that can decide which client to redirect to (e.g. a ClientFactory or ClientRouter). This isn't always necessary, but if your requirements are less-than-trivial the abstraction may help keep things simple.
Both have drawbacks:
Version #1 always gets two instantiated clients. If instantiation is a heavy process, this is not good.
Version #2 hides it's dependencies. That is a well-known anti-pattern.
The perfect solution would be to inject an IClient1Factory and an IClient2Factory and call their factory create methods when needed. That means you still instantiate only one, not both, but you do not hide the dependencies.
As always there is no perfect solution, you now obviously need to write and maintain those two factories. Make sure it's worth it. If Client1/Client2 class instantiation is just a simple new with nothing happening in the constructor, you may want to opt for the simpler Version #1 approach. If it's simple and it works, don't wrap it in too many pattern layers. Only use them if you need them.
what you can do, is to inject ClientX trought an interface for more flexibility as shown in code below :
public class Service<T> where T : IClient
{
private readonly IServiceProvider serviceProvider;
public Service(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public Data GetData<T>(string something)
{
return this.serviceProvider.GetRequiredService<T>().GetData(something);
}
}
As I am learning about Dependency Injection, so I have also shared my understanding (Please correct me wherever you guys feel to do so). The concept behind the following sample is to check the advantage of using Dependency Injection as it helps in implementing loose coupling in the application which will further prevent me from making lots of changes in the project in the case when concrete definitions (classes) tend to change in future.
IEmailService - Interface:
public interface IEmailService
{
void SendMail();
}
EmailService - Class inheriting above interface
public class EmailService : IEmailService
{
public EmailService(string emailFrom, string emailTo)
{
}
public void SendMail()
{
// Code here
}
}
HomeController
public class HomeController : Controller
{
private IEmailService _service;
public HomeController(IEmailService service)
{
_service = service;
}
public IActionResult Index()
{
_service.SendMail();
return View();
}
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
...
services.AddTransient<IEmailService, EmailService>();
...
}
Practical assumption
I assume that earlier there was no parameterized constructor in the EmailService class, but in future, I feel like I need to add a parameterized constructor but it shouldn't have an impact on those controllers (like HomeController) which are using abstraction (interfaces) to access them indirectly.
Unfortunately, when I am running the above code, I am getting the following exception which seems to disappear if I am removing the parameterized constructor from EmailService class.
InvalidOperationException: Unable to resolve service for type 'System.String' while attempting to activate 'DependencyInjectionDemo.Services.EmailService'.
You can register your EmailService using a lambda:
services.AddTransient<IEmailService>(_ => new EmailService("from#", "to#"));
emailFrom and emailTo however seem runtime data, which means that the Controller might be responsible of supplying this information to the IEmailService. Since the EmailService is decoupled from the controller, it means that the controller is not responsible of its creation.
In general, you should prevent needing to initialize your components (EmailService in your case) with runtime data, as explained here, the advice is:
Don't inject runtime data into application components during construction; it causes ambiguity, complicates the composition root with an extra responsibility and makes it extraordinarily hard to verify the correctness of your DI configuration. My advice is to let runtime data flow through the method calls of constructed object graphs.
In your case this basically means changing the IEmailService abstraction to the following:
public interface IEmailService
{
void SendMail(string emailFrom, string emailTo);
}
Hi there i am new to the repository pattern. I would like to have feedback on the approach i am following.
Requirement : Build the menu for the user that is currently logged in.
My Solution :
I created a Service, that will be called by the controller to get the menu items.
public interface IApplicationHelperService
{
List<Menu> GetMenuForRoles();
}
The implementation for the service
public class ApplicationHelperService : IApplicationHelperService
{
private readonly IMenuRepository _menuRepository; //this fecthes the entire menu from the datastore
private readonly ICommonService _commonService; //this is a Service that contained common items eg. UserDetails, ApplicationName etc.
public ApplicationHelperService(IMenuRepository menuRepository,ICommonService commonService)
{
this._menuRepository = menuRepository;
this._commonService = commonService;
}
public List<Menu> ApplicationMenu
{
get
{
return _menuRepository.GetMenu(_commonService.ApplicationName);
}
}
List<Menu> IApplicationHelperService.GetMenuForRoles()
{
return ApplicationMenu.Where(p => p.ParentID == null && p.IsInRole(_commonService.CurrentUser.Roles)).OrderBy(p => p.MenuOrder).ToList();
}
}
Then the CommonService (used for common items needed in the Services eg. CurrentUser
public interface ICommonService
{
IUser CurrentUser { get; }
string ApplicationName { get; }
}
On the class the implements the ICommonService, i get the current user using the context, in other words my service layer does not know about the HttpContext, since there is a possibility that this might by used for another type of application in the future. So this way i can handle by Current User differently for all applications, but my Service Layer will not mind.
So what you should give feedback on is, is this approach to inject this kind of common service into all services a good approach or is there another way of doing this, the reason i ask, is at a later stage i will need the current user's details for auditing purposes or whatever reason presents itself.
Hope this makes sense to someone. :-)
We are using a similar approach. The difference is that, we do not have a CommonService object injected into each service.
We are using WCF and we have written an extension to OperationContext to store Username etc. The properties defined in this extension can be accessed using static method calls. It has an advantage over CommonService implementation; since you are employing IOC, there is not direct way to pass parameters into CommonService in each service call. For instance, if you are sending the username on the WCF calls, you need to set the value of CurrentUser in each constructor.
I do not know whether you are planning to use WCF; but the point is that: if you need to pass variables to your CommonService, you will endup with populating this values inside each constructor. If you are not planning to pass variables, then you can just create a base class for your services and force the developers to use this base class.
Also, you should set the lifetime manager of CommonService as UnityPerResolveLifeTimeManager, in order not to create a new instance in each constructor.Otherwise, you may endup with having different instances in each Service.
I have implemented repository pattern and it works pretty well.
public interface IServiceRepository
{
User GetUser(int id);
User GetUser(string email);
User GetUser(string email, byte[] password);
//SkipCode
}
//Service repository where I keep extended methods for database manipulation
public class ServiceRepository : IServiceRepository
{
private readonly IRepository<User> _userRepository;
private readonly IRepository<Order> _orderRepository;
private readonly IUnitOfWork _unitOfWork;
public ServiceRepository(IRepository<User> userRepository, IRepository<Order> orderRepository, IUnitOfWork unitOfWork)
{
}
//SkipImplementation
}
When I want to access some methods from IServiceRepository in Controller I do this
public class AccountController : Controller
{
private readonly IRepository<OrderDetail> _orderDetailRepository;
private readonly IRepository<UserDetail> _userDetailRepository;
private readonly IServiceRepository _serviceRepository;
public AccountController(IRepository<OrderDetail> orderDetailRepository, IRepository<UserDetail> userDetailRepository, IServiceRepository serviceRepository)
{
_orderDetailRepository = orderDetailRepository;
_userDetailRepository = userDetailRepository;
_serviceRepository = serviceRepository;
}
}
As you see I inject IRepositories and IServiceRepository in this scenario. Sometimes I inject only IRepositories or IServiceRepository depending on a needs.
Question would be maybe I should move all IRepositories into IServiceRepository. And in all controllers embed only IServiceRepository and access IRepositories from IServiceRepository? This implementation looks more clear to me because only IServiceRepository will be injected in controllers. But to access for example one Repositorie<User> from ServiceRepository will need to build and inject all other repositories in ServiceRepository, so it may slow down the whole application. What do you think?
My answer is controversial, so please bear with me :)
To the point
Building and injecting repositories should take almost no time. I assume your repositories do not open any connections when they are created, so do not bother about micro optimisation, just get it working :)
You can merge your interfaces, as long as the result interface is small (say no more than 10 or so methods), focused and has a clear purpose.
Side comments
What is the need for the repository pattern? Do you allow (or in the nearest future plan) to easily switch between databases? For most cases repository is a massive overkill and a maintenance problem.
Consider this code
public interface IServiceRepository
{
User GetUser(int id);
User GetUser(string email);
User GetUser(string email, byte[] password);
//SkipCode
}
What does it tell me? Well, from the generic name I couldn't understand what this interface does, it is like service of a service, abstraction over abstraction. But from the method definitions I see it does something with Users.
Why do you explicitly using IUnitOfWork? Is it not already implemented by the data provider you using?
Instead of all this architecture (of course if possible), just use ORM directly, this is easy to do and maintain, reliable and fast.
Your ServiceRepository seems to be closer to a domain service in a Service Layer than a repository of its own.
A domain service typically coordinates a sequence of interactions with various data repositories, for example loading a customer from a customer repository and a list of orders from an order repository to present a unified view of a customer and all their orders. As such domain services are used to create an operational boundary around an application - abstracting the various sequences of data access.
This is a fine approach, but I think the problem you have is that you have not taken it far enough. If you decide that the operations of the application should be encapsulated into a series of domain services, then there will be no need for a Controller to access repositories. If on the other hand you decide that the Controllers will take that reposibility, and access repositories themselves, then your ServiceRepository class, and others like it, basically become utility classes.
I see that you have two options - improve your service layer to such an extent that controllers no longer need repositories:
public class AccountController
{
public AccountController(IAccountsService service)
{
_service = service;
}
public void SomeActionMethod(Foo someParams)
{
_service.SomeAction(someParams);
}
}
or call the ServiceRepository what it is, a shortcut utility for doing a fixed sequence of data accesses...
public class AccountController
{
public AccountController(ICustomerRepository customerRepo, IOrderRepository orderRep)
{
_customerRepo = customerRepo;
_orderRepo = orderRepo;
}
public void SomeActionMethod(Foo someParams)
{
var utility = new CustomerOrderBuilderUtility(_customerRepo, _orderRepo);
var customerWithOrders = utility.GetCustomerAndOrders(someParams.CustomerId);
// some domain logic...
}
}