I'm writing the following class
public class UserApplication
{
private IUserRepository UserRepository { get; set; }
private IUserEmailerService UserEmailerService { get; set; }
public UserApplication(IUserRepository userRepository, IUserEmailerService userEmailerService)
{
this.UserRepository = userRepository;
this.UserEmailerService = userEmailerService;
}
public bool Authenticate(string login, string pass)
{
// Here I use UserRepository Dependency
}
public bool ResetPassword(string login, string email)
{
// Here I only use both Dependecies
}
public string GetRemeberText(string login, string email)
{
// Here I only use UserRepository Dependency
}
}
I'm using Unity for manage my instances so I realised that I only use both dependencies on only one method so when I ask the container to give a instance for this class both dependencies are inject into this class but I don't need the two instances for all methods so in Authenticate user I only need the repository.
So am I wrong doing this? Is there another way that only have the dependecy I use for all cases in this class?
I think of using the Command Pattern to that so I class 3 classes with one method and only the dependencies I need inside that like this:
public class AuthenticateUserCommand : ICommand
{
private IUserRepository UserRepository { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public void Execute()
{
// executes the steps to do that
}
}
public class ResetUserPasswordCommand : ICommand
{
private IUserRepository UserRepository { get; set; }
private IUserEmailerService UserEmailerService { get; set; }
public string Login { get; set; }
public string Email { get; set; }
public void Execute()
{
// executes the steps to do that
}
}
Another approach is to create a role-specific interface for each behavior. So you'd have IUserAuthenticationService, IUserPasswordResetService, and IUserRememberPasswordService. The interfaces could be implemented by a single class, such as UserApplication or they could be implemented with individual classes to maintain SRP. The command pattern you describe has a similar advantage for SRP. One issue with the command pattern is that those dependencies still have to be provided by something. If the dependencies are provided by the controller, then you still have to get the dependencies to the controller in the first place and you are left with a similar problem as your first example.
The trade-off in the role-specific interface case as well as the command pattern is a loss of cohesion. The cost of this is certainly a matter of preference and perspective as is the degree to which you want to enforce SRP. On one hand, the cohesion provided by having a single class handle authentication related behavior can be beneficial. On the other hand, it can lead to a dependency misalignment as you describe.
I usually implement a form of the command pattern as you are considering doing. However, it also has elements of what eulerfx has mentioned. I just call them tasks. For example:
public interface ITask
{
void Execute();
}
public interface IAuthenticateTask : ITask {}
public interface IResetPasswordTask : ITask {}
I then implement these and have the required dependencies injected. So I have role specific interfaces and implementations.
I would not go with the service locator as you stated in your answer bit.
When I do have a situation where I need access to various tasks as I do in the controller of an ASP.NET MVC project I use property injection instead of constructor injection. I just have my DI container (I use castle) require certain injections based on a convention at runtime.
In this way I can still easily test the controller since I do not need to provide all the constructor injected objects but only those properties that I need for the test, with the added benefit that certain injected properties will still be required just as would be provided by constructor injection.
update:
There are a couple of options available using this approach. The main interface one would be interested in for a task is the role-specific one. The inherited interface(s) such as ITask would be only for convenience in simple cases. It can be extended also with generics:
public interface ITask<TInput>
{
void Execute(TInput input);
}
public interface IOutputTask<TOutput>
{
TOutput Execute();
}
public interface IOutputTask<TOutput, TInput>
{
TOutput Execute(TInput input);
}
Once again these are for convenience:
public interface IAuthenticateTask : IOutputTask<bool> {}
// or
public interface IAuthenticateTask : IOutputTask<AuthenticationResult> {}
You could work just on the role level:
public interface IAuthenticateTask
{
AuthenticationResult Execute(string username, string password);
}
One need only rely on the role-specific interface for dependencies.
So am I wrong doing this?
No. 2 dependencies are not the end of the world, they don't make the constructor bloated or unreadable.
Previously given answers would be good fits for cases when you have 3-4+ dependencies though.
You could also occasionally pass a particular dependency as a parameter to a method if it is only used in that method. In this sense, you might want to give Unity's method call injection a try although I'm not sure it was precisely intended for that purpose.
Related
In my startup.cs I have code like this
services.AddScoped<IFileStorage, DiskFileStorage>();
service.Add<IImageHandler, ImageHandler>();
public class ImageHandler
{
ImageHandler(IFileStorage fileStorage, ...){}
}
now I want to add another class, OtherHandler, that takes a IFileStorage interface, but with another implementation, something like this
services.AddScoped<IFileStorage, NetworkFileStorage>();
public class OtherHandler:IOtherHandler
{
OtherHandler(IFileStorage, fileStorage)
}
Now how do i configure stuff so that the OtherHandler would use the NetworkFileStorage implementation for IFileStorage and anything else would use a default DiskFileStorage implementation?
Update:
Thanks to gunr2171 comment, I discovered that I could do a
services.AddScoped<IOtherHandler>(provider => new OtherHandler(provider.GetRequiredService<NetworkFileStorage>())); to get a specific implementation. But still curious if it is possible if I for some reason wanted to use an interface.
So, based on my understanding this is your scenario:
public interface IFileStorage
{
}
public class NetworkFileStorage: IFileStorage
{
}
public class DiskFileStorage: IFileStorage
{
}
You also have a couple of services depending on the IFileStorage service:
public class ImageHandler: IImageHandler
{
public ImageHandler(IFileStorage fileStorage)
{
}
}
public class OtherHandler: IOtherHandler
{
public OtherHandler(IFileStorage fileStorage)
{
}
}
You want to register your services so that both of the followings hold true:
instances of ImageHandler are built by injecting NetworkFileStorage
instances of OtherHandler are built by injecting DiskFileStorage
For simplicity, I'll suppose that all the involved types are implemented so that it is ok to register them as singletons. This depends on the actual implementation, in any case the pattern that I'm going to show you doesn't depend on the actual lifetime of the involved types.
First of all, register the concrete implementations of the IFileStorage interface. You need to register the classes (not the interface): the purpose of this is making sure that the DI container knows these types and it is able to provide you instances of both types.
services.AddSingleton<NetworkFileStorage>();
services.AddSingleton<DiskFileStorage>();
Now, you can register an implementation for the IImageHandler service.
You will use the ImageHandler class as the implementing type and you will also provide a factory method to the DI container: by doing so, you are able to select the implementation of IFileStorage to be injected (in this case you will select the NetworkFileStorage type).
services.AddSingleton<IImageHandler>(sp =>
{
var fileStorage = sp.GetRequiredService<NetworkFileStorage>();
return ActivatorUtilities.CreateInstance<ImageHandler>(sp, fileStorage);
});
You can do a similar thing to register the OtherHandler class as the implementation for the IOtherHandler service, and select the class DiskFileStorage as the type being injected in the constructor of OtherHandler:
services.AddSingleton<IOtherHandler>(sp =>
{
var fileStorage = sp.GetRequiredService<DiskFileStorage>();
return ActivatorUtilities.CreateInstance<OtherHandler>(sp, fileStorage);
});
Let me add a final note on your design. There is something wrong with it.
It seems to me that the ImageHandler class is somewhat strongly coupled with the NetworkFileStorage class, while the OtherHandler class is somewhat strongly coupled with the DiskFileStorage class.
I would expect both of these classes to work fine with any implementation of the IFileStorage interface. If these classes do really depend only on the behavior described by the IFileStorage interface, then any actual implementation of that behavior should be fine for them to work as expected. This is basically a violation of the Liskov Substitution Principle.
If this is not the case, maybe the interface IFileStorage is not a useful abstraction for your domain model and you should considered to redesign it or to define two different interfaces (one suited to the needs of the ImageHandler class and the other suited to the needs of the OtherHandler class).
I think there might be a more flexible approach here. It uses Adapter pattern for your services, allowing you to stay away from registering concrete implementations, and doesn't force you to instantiate every type manually that uses some FileStorage implementation.
// A generic storage that can be used for any scenario
public interface IFileStorage<T> where T : IFileAdapter
{
protected T Adapter { get; }
Task Handle();
}
// a base interface that defines the shape of adapter
public interface IFileAdapter
{
Task Handle();
}
// copy interfaces to separate the services
public interface ILocalFileAdapter : IFileAdapter
{
}
public interface IRemoteFileAdapter : IFileAdapter
{
}
// specific implementations
public class RemoteFileAdapter : IRemoteFileAdapter
{
private readonly ILogger<RemoteFileAdapter> logger;
public RemoteFileAdapter(ILogger<RemoteFileAdapter> logger)
{
this.logger = logger;
}
public Task Handle()
{
this.logger.LogWarning("Handling file remotely");
return Task.CompletedTask;
}
}
public class LocalFileAdapter : ILocalFileAdapter
{
private readonly ILogger<LocalFileAdapter> logger;
public LocalFileAdapter(ILogger<LocalFileAdapter> logger)
{
this.logger = logger;
}
public Task Handle()
{
this.logger.LogWarning("Handling file locally");
return Task.CompletedTask;
}
}
// generic storage that uses an adapter to handle the scenario
public class FileStorage<T> : IFileStorage<T> where T : IFileAdapter
{
public FileStorage(T fileAdapter)
{
Adapter = fileAdapter;
}
public T Adapter { get; }
public Task Handle()
{
return this.Adapter.Handle();
}
}
Register your services like below :
builder.Services.AddSingleton<ILocalFileAdapter, LocalFileAdapter>();
builder.Services.AddSingleton<IRemoteFileAdapter, RemoteFileAdapter>();
// aspnet.core allows you to register generic services
builder.Services.AddSingleton(typeof(IFileStorage<>), typeof(FileStorage<>));
And this is how you use your IFileStorageService:
public WeatherForecastController(IFileStorage<ILocalFileAdapter> localFileStorage, IFileStorage<IRemoteFileAdapter> remoteFileStorage)
{
localFileStorage.Handle();
remoteFileStorage.Handle();
}
// which will log :
// Handling file locally
// Handling file remotely
I'm wondering if it's possible to have a decorator for 1 of multiple implemented interfaces in C#. I'm leaning towards no, but maybe.
Here's what I mean
public abstract class Auditable
{
public string CreatedBy { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime ModifiedAt { get; set; }
public string ModifiedBy { get; set; }
}
public class MyClass : Auditable
{
// <...> properties
}
public interface IWriteRepository<T> : where T : Auditable
{
T Create(T entity);
T Update(T entity);
}
public class AuditRepositoryDecorator<T> : IWriteRepository<T> where T : Auditable
{
private readonly IWriteRepository<T> _decorated;
// <...> ctor with injects
public T Create(T entity)
{
entity.ModifiedAt = time;
entity.CreatedAt = time;
entity.CreatedBy = invoker;
entity.ModifiedBy = invoker;
return _decorated.Create(entity);
}
public T Update(T entity)
{
entity.ModifiedAt = time;
entity.ModifiedBy = invoker;
return _decorated.Update(entity);
}
}
public interface IMyClassRepository : IWriteRepository<MyClass>
{
MyClass Get(int id);
}
So I would like to be able to depend on IMyClassRepository repository and whenever Create or Update would get invoked it would go through AuditRepositoryDecorator. It's a piece of logic that is executed a lot and I think it would be much simpler to have as a decorator instead of having a composition relation to some interface that does the same.
IAuditableRepository is never instantiated directly, as it's would always be implemented by another interface, so I think it might not be possible to do what I want to achieve.
I'm using the default dnc2.1 DI framework with Scrutor for decorations.
What you are trying to achieve is not possible. This isn't a limitation of the used DI Container, but rather a constraint of the .NET Type system. I often advise developers that are in DI trouble to, for the sake of understanding, remove the DI Container from the equation and instead build object graphs by hand. This works well in your situation, as I'll demonstrate below.
Assume you have an IMyClassRepository consumer:
public class RepoConsumer
{
RepoConsumer(IMyClassRepository repo) ...
}
And an IMyClassRepository implementation:
public class MyClassRepositoryImpl : IMyClassRepository
{
...
}
Now let's create the object graph for RepoConsumer that uses AuditRepositoryDecorator<MyClass>:
var repo = new MyClassRepositoryImpl();
var decoratedRepo = new AuditRepositoryDecorator<MyClass>(repo);
var consumer = new RepoConsumer(decoratedRepo); // <-- COMPILE ERROR
When you compile this code, you'll notice that the C# compiler will generate an error on the new RepoConsumer line. This is because RepoConsumer expects an IMyClassRepository. Although MyClassRepositoryImpl implements IMyClassRepository, AuditRepositoryDecorator<MyClass> does not implement IMyClassRepository.
To solve this, you might try letting AuditRepositoryDecorator<T> implement IMyClassRepository, but that will obviously be ugly, because the decorator will have to implement a dozen of interfaces, for each entity in your system.
But what this exercise proves, is that the problem is not so much with the DI Container, but rather that the type system simply not permits you to build an object graph of this. And since the type system doesn't allow you to, the DI Container certainly won't allow it. It can't work around the type checks of the type system. Fortunately.
But the solution to your problem is actually really straightforward: remove the specific IMyClassRepository and let consumers depend on IWriteRepository<MyClass> instead. This might seem a disappointing solution, but there is a myriad of problems surrounding deriving from generic interfaces. Just accept the fact that consumers depend on such generic abstraction. It takes some time, but eventually, you will start to love and appreciate this style of programming.
But, of course, this still leaves us with the question of how to add new methods, such as MyClass Get(string). There are multiple solutions, such as:
Implement it as extension method (only possible when the method itself requires access to the interface itself, not to the class's internals)
Define a separate interface, which might be a good idea in general, according to the Interface Segregation Principle
the most used approach in these cases is the repository pattern as explained here in my answer: How do I avoid code repetition when defining a class of functions that only vary the data type of the parameters they handle?
in your case this is the classes hierarchy:
public interface IWriteRepository<T> : where T : Auditable
{
T Create(T entity);
T Update(T entity);
}
public abstract class WriteRepositoryBase<T> : IWriteRepository<T> where T : Auditable
{
//implement create and update
}
public interface IMyRepository : IWriteRepository<MyClass>
{
MyClass Get(string id);
}
public class MyRepository : WriteRepositoryBase<MyClass>, IMyRepository
{
//implement Get
}
I have two interfaces implemented by one main class. How can i refactor my code in a way that on implementing each contract, the methods of each contract has a different value for a parameter such as DatabaseName.
Example :
Class1 Implements Interface1,Interface2
Interface1.GetData() has DatabaseName set to Database 1
Interface2.GetData() has DatabaseName set to Database 2
I can configure those value in the methods GetData() but i want a cleaner way of doing it.
Any pattern recommendation be that DI ,Domain driven ,even basic inheritance example which accomplishes the above is what i am looking for.
It sounds like all you need is explicit interface implementation:
public class Class1 : Interface1, Interface2
{
// Note the lack of access modifier here. That's important!
Data Interface1.GetData()
{
// Implementation for Interface1
}
Data Interface2.GetData()
{
// Implementation for Interface2
}
}
Obviously the two methods can call a common method with a parameter to specify the database name or similar.
Refactoring is usually motivated by noticing a code smell and the very fact that you ended up in a situation where you have to implement 2 abstraction which expose similar functionality is the code smell.
Without having more understanding of the problem I might not be able to provide you a conclusive answer but with limited understanding this is what I would propose. Have 2 different concrete implementation each implementing one interface and have a factory which would be injected to client and make the client make the deliberate decision which one of these implementation is needed. In case these concrete classes share common functionality you can always abstract that into a common parent class.
public interface ISQLReader
{
string GetData();
}
public interface IOracleReader
{
string GetData();
}
public abstract class Reader
{
protected void CommonFunctionaility()
{
}
}
public class MSSQLReader : Reader, ISQLReader
{
public string GetData()
{
return "MSSQL";
}
}
public class OracleReader : Reader, IOracleReader
{
public string GetData()
{
return "Oracle";
}
}
public interface IReaderFactory
{
OracleReader CreateOracleReader();
MSSQLReader CreateMSSQLReader();
}
public class ReaderFactory : IReaderFactory
{
public MSSQLReader CreateMSSQLReader() => new MSSQLReader();
public OracleReader CreateOracleReader() => new OracleReader();
}
public class ReaderClient
{
private IReaderFactory _factory;
public ReaderClient(IReaderFactory factory)
{
this._factory = factory;
}
}
Explicit interface implementation is technique that should restrict usage of the functionality until the client has made and explicit cast there by making a deliberate decision.
I have a series of classes each with several dependencies according to their role. These dependencies are being injected into the constructor. An example would be:
public class UserViewModel
{
//...
public UserViewModel(IDataService dataService,
INotificationService notificationService,
IDialogService dialogService,
INavigationService navigationService)
{
this.DataService = dataService;
this.NotificationService = notificationService;
this.DialogService = dialogService;
this.NavigationService = navigationService;
}
}
As you can see, there are several arguments to set. I could write an interface like the following:
public interface IInteractionService
{
public INotificationService NotificationService { get; set; }
public IDialogService DialogService { get; set; }
public INavigationService { get; set; }
}
and pass the injected InteractionService implementation to the UserViewModel's constructor in one piece:
public UserViewModel(IDataService dataService,
IInteractionService interactionService) {}
and use it like:
this.InteractionService.NotificationService.Publish(message);
Are there any issues with using an interaction interface holding interface properties in terms of design patterns/principles? Or is there a better way to look at it?
Thanks for any advice...
In general, you should not create "God" service with different services inside. It breaks Single Response Principle (SRP).
But I do not understand how it can be that DI injects you null against instance of service? May be you should fix this behaviour against creating "God" service?
IMO, dependency injection in a constructor is a way to hell. Could you predict the final number of dependencies during the lifetime of your application? Do you really want to modify ctor's code everytime? Do you really want to initialize all dependencies at once, instead of lazy initialization?
MEF, e.g., can inject private fields in lazy manner.
You definitely shouldn't test for null injected values. If your DI-framework doesn't make these tests itself, then throw it away and use normal one.
To put this in concise language...
Aim:
To create a class which can load and save a list of objects to/from a data source.
Current Method:
I have created a class which accepts two delegates as construction parameters:
private class Foo
{
public delegate List<object> LoadObjectsDelegate();
public delegate void SaveObjectsDelegate(List<object> data);
private LoadObjectsDelegate _loadDelegate;
private SaveObjectsDelegate _saveDelegate;
public Foo(LoadObjectsDelegate loadDelegate, SaveObjectsDelegate saveDelegate)
{
_loadDelegate = loadDelegate;
_saveDelegate = saveDelegate;
}
public List<object> Objects {get; private set;}
public void Load()
{
Objects = _loadDelegate.Invoke();
}
public void Save()
{
_saveDelegate.Invoke(Objects);
}
}
i was wondering if there was a cleaner way to do this.
By the looks of it i'd say you're trying to implement the Repository pattern, with some extended functionality. I also see no point in trying to inject the load and save logic, as it's the repository's job to implement them. If the logic of loading and saving objects is the same for all objects in your domain, have it implemented in a base class, and override it in derived classes if needed. This article on SO could give you some ideas on how to deal with this pattern.
Well for one thing I'd make it generic (Foo<T>) - your callers can always specify object if they really want, and it means they can use it in a more strongly typed way if necessary.
Currently I'm not sure the class is really adding much value, to be honest. It's really just grouping the three values together - and that's all. If that's what you intended, that's fine... but it feels a bit anaemic to me.
It is not cleaner, just another approach. If the behaviour which you are specifying in the delegates does not vary too much, consider the Template Pattern.
private abstract class AbstractFoo
{
public List<object> Objects { get; private set; }
public List<object> Load();
public abstract void Save(List<object> data);
// add common functionality
}
private class ConcreteFoo : AbstractFoo
{
public override List<object> Load()
{
// do specific stuff
}
public override void Save(List<object> data)
{
// do specific stuff
}
}
The disadvantage is that you need a class for each specific behaviour. Thus: If the behaviour given by the delegates varies a lot or you need to dynamically load different behaviours, I find your delegate approach is suitable. I usually find the Template Pattern easier to understand and easier to unit test.
You can go one step further: Behavior is specified by inheritance in the Template Pattern. Instead of inheritance you can specify the behaviour by reference if you choose a more abstract approach with an interface:
private interface IRepository
{
List<object> Load();
void Save(List<object> data);
}
private class FooBar
{
private IRepository repository;
public List<object> Objects { get; private set; }
public FooBar(IRepository repository)
{
this.repository = repository;
}
public void Load()
{
Objects = repository.Load();
}
public void Save()
{
repository.Save(Objects);
}
}
If you need some specific behaviour you need to implement a class derived from IRepository. This approach is even more easier to understand and unit test than the Template Pattern. I often end up replacing the Template Pattern with the latter approach.