Facade with two services inside and dependency injection - design pattern approach - c#

I want to create Facade class to handle few operations on two services.
For contacting those services I've got proxy classes.
Having abstract Proxy and derived proxy per service - how can I create this part of architecture, to avoid Resolving in Facade?
class Facade
{
private Proxy proxy1;
private Proxy proxy2;
public Facade()
{
//I don't like this part
proxy1 = ...Resolve<Proxy1Type>();
proxy2 = ...Resolve<Proxy2Type>();
}
public void Do()
{
proxy1.Call();
proxy2.Call();
}
}
abstract class Proxy {public void Call();}
class Proxy1Type : Proxy {public void override Call(){}}
class Proxy2Type : Proxy {public void override Call(){}}
What design pattern should I use to fix this case?
EDIT
Optionally I should go in this solution, but still don't like it much
class Facade
{
private IProxy proxy1;
private IProxy proxy2;
//I feel it's still wrong
public Facade(IProxy1Type p1, IProxy2Type p2)
{
proxy1 = p1;
proxy2 = p2;
}
public void Do()
{
proxy1.Call();
proxy2.Call();
}
}
interface IProxy { void Call();}
interface IProxy1Type : IProxy{}
interface IProxy2Type : IProxy {}
class Proxy1Type : IProxy1Type { public void Call() { } }
class Proxy2Type : IProxy2Type { public void Call() { } }

There are two opposite approaches and you shown them both in the question. You can either resolve dependencies inside a class using Service Locator (first sample) or inject them from the outside using Dependency Injection.
Dependency Injection (constructor injection in your case) has a few advantages:
It's more clear what is needed for the Facade class to operate properly, since you do not need to dig inside the class to figure out what it'll try to resolve (and when).
It's easier to unit test the Facade class, since you're able to inject test doubles via constructor; there is no need to configure a DI container in the unit tests.
You can read more about Service Locator (and why you should avoid using it) in this post.

Related

.net 7 dependency injection, Mulltiple implementation of same interface

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

Factory Pattern of IOC, always need to instantiate?

I'd like my app to be not strictly tied to an IOC, so basically my application should need to call an IOC factory pattern that solve the specific implementation on runtime.
So, first off I've created my interface:
IIOCService
interface IIOCService
{
void RegisterSingleton<RegisterType>()
where RegisterType : class;
void RegisterMultiple<RegisterType>()
where RegisterType : class;
void RegisterMultiple<RegisterType>(IEnumerable<Type> implementationTypes);
// and so on
}
then an implementation of IIOCService, using TinyIOC
class TinyIOCServiceImpl : IIOCService
{
private static readonly TinyIOCServiceImpl _Current = new TinyIOCServiceImpl();
public static TinyIOCServiceImpl Current
{
get
{
return _Current;
}
}
TinyIoC.TinyIoCContainer container;
public TinyIOCServiceImpl()
{
container = TinyIoC.TinyIoCContainer.Current;
}
public void RegisterSingleton<RegisterType>()
where RegisterType : class
{
container.Register(typeof(RegisterType)).AsSingleton();
}
// ...and so on
}
For the class that decides to resolve the implementation of the IOC container, I've created an IOCFactory
IOCFactory
class IOCFactory
{
public enum IOC { TinyIOC }
public IIOCService GetService(IOC iocType)
{
switch (iocType)
{
case IOC.TinyIOC:
return TinyIOCServiceImpl.Current;
default:
throw new NotSupportedException();
}
}
}
Now my question is:
Should I need to reinstantiate the factory for every class where IOC is needed or there is some more elegant way?
IIOCService iocService = new IOCFactory().GetService(IOCFactory.IOC.TinyIOC);
// code needed everytime I need to use IOC (i.e. ServiceLocator, ViewModelLocator, etc.)
// is this code a bit redundant ???
I agree that creating a wrapper around your IOC container is a bit redundant. But, if you need to call your IOC container to resolve a specific, on run-time determined, instance of an interface, you can create a resloving interface (not with the factory pattern, but staying within the IOC pattern). Something like this (this is too basic, just so you can get the idea):
public interface IResolve {
public T Resolve<T>();
}
You can create an implementation for this specific interface and expose it to your IOC container. There is no issue doing this in a single instance pattern.
When you need to resolve something in a class that was resolved by the IOC container, just add the IResolve to your constructor and you can address the IOC container without a dependency on whatever brand of IOC container is used.
I hope this brought some clarity for you?

What are the differences between Decorator, Wrapper and Adapter patterns?

I feel like I've been using these pattern families quite many times, however, for me it's hard to see the differences as their definitions are quite similar. Basicaly it seems like all of them is about wrapping another object or objects to extend or wrap their behavior with extra stuff.
For a quick example implementing a caching mechanism over a repository pattern seems to be this situation. Here is a quick sample C# code I would probably start with.
public interface IRepository {
IEnumerable<T> GetItems<T>();
}
public class EntityFrameworkRepository : IRepository {
...
}
public class CachedRepository : IRepository {
private IRepository _repository;
private ICacheProvider _cache;
public CachedRepository(IRepository repository, ICacheProvider cache) {
this._repository = repository;
this._cache = cache;
}
public IEnumerable<T> GetItems<T>() {
...
}
}
Which one of these patterns apply to this situation for example? Could anyone clarify briefly the differences in theory and in practice?
In theory they are the same, it's the intent that differentiates one pattern from the other:
Decorator:
Allows objects to be composed/add capabilities by wrapping them with a class with the same interface
Adapter:
Allows you to wrap an object without a known interface implementation
so it adheres to an interface. The point is to "translate" one interface into another.
Wrapper:
Never heard of this as a design pattern, but I suppose it's just a common name for the above
The example you specify I would categorize as a decorator: The CacheRepository decorates an IRepository to add caching capabilities.
A programmer may write a class A with a focus on holding an object of another class B. Class A would be referred to as a wrapper for class B. Why have class A wrap around class B? To decorate or adapt it. Decorators and adapters are wrappers.
Imagine that class A is written such that it implements the interface of class B by calling the methods of its class B object. It could then be used in place of class B. There's no point in this other than the fact that it gives the programmer the opportunity to add some code before or after the calls to the methods of the class B object. This version of class A would be called a decorator of class B. Decorators leave the interface the same while adding some behavior.
interface ICatInterface {
public void wakeUp();
}
class Cat implements ICatInterface {
public void wakeUp() {
System.out.println("I came. I saw. I napped.");
}
}
class YogaCat implements ICatInterface {
private ICatInterface cat;
public YogaCat(ICatInterface cat) {
this.cat = cat;
}
public void wakeUp() {
System.out.println("[Stretch]"); // <- This is the decoration.
cat.wakeUp();
}
}
See this example of a more complicated way to use this pattern for composing objects of differing behavior during runtime.
Imagine now that class A is written such that it implements some interface C, but is implemented mostly via calls to the methods of its class B object. This is a way to translate the methods available in class B to interface C. This version of class A would be called an adapter of class B. It's like when you want to charge your phone. There are adapters that go from wall or car power source to USB port. Adapters change the interface to some other interface, but don't necessarily add any behaviors.
interface TakeDirectionsInterface {
public void turnLeft();
public void turnRight();
public void go();
public void stop();
}
class Driver {
public enum TurnDirection
{
CLOCKWISE, COUNTERCLOCKWISE;
}
public enum FootPedal
{
ACCELERATOR, BRAKE, CLUTCH;
}
public void turnSteeringWheel(TurnDirection direction) {
System.out.println("Turning the steering wheel " + direction.toString() + ".");
}
public void pressPedal(FootPedal pedal) {
System.out.println("Pressing the " + pedal.toString() + "pedal.");
}
}
class DriverAdapter implements TakeDirectionsInterface {
private Driver driver;
public DriverAdapter(Driver driver) {
this.driver = driver;
}
public void turnLeft(){
driver.turnSteeringWheel(Driver.TurnDirection.COUNTERCLOCKWISE);
}
public void turnRight(){
driver.turnSteeringWheel(Driver.TurnDirection.CLOCKWISE);
}
public void go(){
driver.pressPedal(Driver.FootPedal.ACCELERATOR);
}
public void stop(){
driver.pressPedal(Driver.FootPedal.BRAKE);
}
}

Dependency property and constructor parameters with Unity

Let's say in C# I have a class called A
public class A : IInterfaceA
{
[Dependency]
B _b;
}
Then in B class I have a constructor like this:
public class B
{
...
public B(string someParam) { ... }
...
}
Now, I register class A like this:
_unityContainer.RegisterType<IInterfaceA, A>("RegistrationA");
and to resolve the interface I do:
_unityContainer.Resolve<IInterfaceA>("RegistrationA", new ParameterOverride("someParam", "The param."));
Now I want to know if it is good practice to resolve the class and pass the parameters like this or I should do it another way.
Thanks a lot :)
First of all the code you posted does not work: in fact you're overriding the parameter of class A, while in your code the constructor with the parameter is B.
Generally speaking, using parameter override is not a good practice in my opinion (unless some very specifical context like a console application or a web service using an existing container but it's avoidable in most cases) for these reason:
Using Resolve looks like a Service locator: anti-pattern nowadays. You will find a lot of discussion googling about.
Using ParameterOverride means that the client (the caller of Resolve) knows exactly the type mapped in the container and wants that type initialized with a specific parameter. But this is just the opposite of inversion of control.
The best way is to use an abstract factory. You can add in your code and use a more flexible and SOLID abstract factory:
public interface BFactory {
B Create(string bparam);
}
public class BFactoryUnity : BFactory {
private IUnityContainer container;
public BFactoryUnity(IUnityContainer container) {
this.container = container;
}
public B Create(String bParam) {
var b = new B(bParam);
container.BuildUp(b);
return b;
}
}
So you can register:
_unityContainer.RegisterType<IInterfaceA, A>("RegistrationA")
.RegisterType<BFactory, BFactoryUnity>();
Now the client can resolve only the factory and use it:
var bFactory = _container.Resolve<BFactory>();
var b = bFactory.Create();
Now, in a big application you will need a lot of similar factories. To avoid the boilerplate code of abstract factories and implementations you can find in the web some implementation of automatic abstract factory extensions.

Initialising fields with initial values with Ninject

I'm currently trying to work out how to set the initial values for some fields using Ninject.
I have something like this:
public class SomeClass
{
private ISomething _something;
public SomeClass(string someParam)
{
}
public void DoAThing()
{
_something.DoSomething();
}
}
My dilemma comes about in the setting of _something to an initial value, given I don't want the class to know anything about which default implementation of ISomething to use, is there a way of achieving this in Ninject?
I should add that passing the initial values in via the constructor is not an option.
I should also add that this is in a class-library, so any information on how and when the setup of the kernel & injection should take place would be great :)
Elaboration: It seems that people could be getting confused, I am not trying to get an ISomething into the class (it isn't a dependency), rather, the default implementation of ISomething is the dependency, this is why I went for the service-locator pattern, for actual dependencies I would of course have them in the constructor.
Thanks.
Yes, it's not very good to have highly coupled classes, thus depending on abstractions is a good choice. But hiding your dependencies is not very good solution. Make them visible to clients of your class, and use dependency injection to provide concrete implementations of dependencies to your class:
public class SomeClass
{
private ISomething _something;
public SomeClass(ISomething something, string someParam)
{
_something = something;
}
public void DoAThing()
{
_something.DoSomething();
}
}
Also consider to create factory, which will provide default implementation of ISomething to created SomeClass objects.
In the end I decided to go with a static IOC access class to allow my code to gain access to the core Ninject Kernel used by the class library for the main injection.
So:
internal static class IOC
{
private static readonly IKernel _kernel;
static IOC()
{
_kernel = new StandardKernel(new IModule[] {
new SomethingModule(),
});
}
static T Get<T>()
{
return _kernel.Get<T>();
}
}
internal sealed class SomethingModule : StandardModule
{
public override void Load()
{
Bind<ISomething>().To<ConcreteSomething>(
new ConstructorParam("arg", "value"));
}
}
Then in my previous class:
public class SomeClass
{
private ISomething _something;
public SomeClass(string someParam)
{
_something = IOC.Get<ISomething>();
}
public void DoAThing()
{
_something.DoSomething();
}
}
Now I can get concrete implementations and even have them initialised with default values to boot!
The way of getting the concrete classes initialised with default values is a little flimsy, but I'm sure there are smarter ways of achieving this in Ninject, but it does appear that a hybrid solution of service-locator-esque code and Ninject works quite well!
BTW I believe you could also have multiple IOC containers in differing scopes (themselves passed along via Ninject :P) to prevent creating a behemoth "everything everywhere" kernel.
Hope this helped someone!

Categories