Constructor Injection Only When Needed - c#

I am looking for a way to inject an interface into a class only when it needs to be used.
For context I am trying to set up publish/subscribe messaging between two different projects, and to do this I am using both RabbitMQ and Azure Service Bus to suit different needs. To determine which one I want to use I use a boolean value which is set in app settings, like so:
if (AppSettingsProvider.MessagingEnabled)
{
if (AppSettingsProvider.AzureServiceBusEnabled)
{
services.AddSingleton<IEventBus, EventBusServiceBus>(
sp =>
{
var serviceBusPersistentConnection = sp.GetRequiredService<IServiceBusPersistentConnection>();
var scope = sp.CreateScope();
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>();
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionManager>();
var subscriptionClientName = AppSettingsProvider.SubscriptionName;
return new EventBusServiceBus(serviceBusPersistentConnection, logger, eventBusSubcriptionsManager, subscriptionClientName, scope);
});
}
else
{
services.AddSingleton<IEventBus, EventBusRabbitMQ>(
...
}
}
I have an if statement that wraps all of this checking MessagingEnabled. Ideally I don't want either implementation to be set up if messaging is turned off.
My issue here is that IEventBus is injected in different event publishing classes, however if I have messaging turned off I get exceptions that there is no instantiation of the injected IEventBus. As an example:
public class EventBusPublisher : IEventBusPublisher
{
private readonly IEventBus _eventBus;
private readonly IMapper _mapper;
public EventBusPublisher(IMapper mapper, IEventBus eventBus)
{
_mapper = mapper;
_eventBus = eventBus;
}
I thought maybe if I made the IEventBus nullable it may solve this issue however it has not.
This class will never be used if messaging is turned off, so there should be no problems with there not being an event bus implementation available in this case. Is there a way to, I guess tell the class its okay that there is no implementation for it?
Thanks.

It's common practice to provide a null implementation that does nothing, a common example being the NullLogger.
You can register that implementation for IEventBus, if messaging is disabled.
Depending on your use case, the class could either just do nothing, if methods are called, or possibly throw an InvalidOperationException.
Of course, it would technically be possible to register null like this:
services.AddSingleton<IEventBus>(factory => null);
But I would strongly advise against that, because now you would have to check your dependency for null everywhere and kind of defeats the purpose of DI.

Related

Decide implementation at runtime using dependency injection

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);
}
}

Is it bad If I use the ServiceProvider interface to resolve my properties in .NET Core for Dependency Injection

Is it bad If I use the ServiceProvider interface to resolve my properties in .NET Core for Dependency Injection
let say I have the following
private readonly IRecipeRepository _recipeRepository;
private readonly IMediaResource _resourceUpload;
private readonly IAWSMedia _awsMedia;
and then do this
public RecipeService(IServiceProvider service)
{
_recipeRepository = service.GetService<IRecipeRepository>();
_resourceUpload = service.GetService<IMediaResource>();
_awsMedia = service.GetService<IAWSMedia>();
}
instead of this
public RecipeService(IRecipeRepository recipeRepo, IMediaResource media, IAWSMedia awsMedia )
{
_recipeRepository = recipeRepo;
_resourceUpload = media;
_awsMedia = awsMedia ;
}
The first bit of code is called the service locator anti-pattern, as in something you should not do. However, the answer to your question depends on context you have not provided.
In the majority of cases, no, you should not just inject IServiceProvider. However, in some scenarios, you have no choice but to: namely with things in singleton scope. If you have a singleton-type class, an IHostedService implementation, etc., you cannot inject anything but other singleton-scoped services. If you need something in a different scope like a DbContext, then you can only get that by injecting IServiceProvider and creating a scope:
using (var scope = _serviceProvider.CreateScope())
{
var foo = scope.ServiceProvider.GetRequiredService<Foo>();
// do something with foo;
}
However, remember that the instance retrieved is tied to the scope. In other words, when the using statement closes, it will be disposed. Therefore, you need to do any work with that instance inside that scope. You cannot do something like set an instance variable on your class, and the attempt to use it later, as you'll then get an ObjectDisposedException.

How to instantiate outside of a constructor?

How to replicate this code with Autofac syntax?
public static class MenuConfig
{
public static void Initialize()
{
var _menuService = DependecyFactory.GetInstance<IMenuService>();
Parameters.Menu = _menuService.Menu();
}
}
Before calling this a "duplicate question" please note that I'm looking for an Autofac command. I CANNOT inject the interface anywhere and then call "Resolve". What I need to is perform an "InstancePerRequest" inline and uninjected so I don't have to do this:
var _service = new Service(new Dependency(new context()));
LightInject has a method that allows instantiation from an interface OUTSIDE of a constructor like this:
var _service = DependecyFactory.GetInstance<IService>();
What is the equivalent method for Autofac?
When calling containerBuilder.Build() you get back a container which implements IContainer and ILifetimeScope, whenever you get hold of one of these interfaces, you can resolve types from it:
container.Resolve<IService>();
If you want this container to be static, you could add the container as a static property to the Program or Startup class (depending if you're creating a Console or ASP.NET application).
Remember that the root container will be around for the entire duration of your application, so this can result in unwanted memory leaks when used incorrectly. Also see the warning in the documentation.
Still, it's perfectly possible to do the memory management yourself by resolving an Owned<> version from your interface:
using (var service = Program.Container.Resolve<Owned<IService>>())
{
service.Value.UseService();
}
Anyway, since you mention a static class in the comments, the best solution is to change that into a non-static class and register it as a singleton with Autofac. Then you can inject a Func<Owned<IService>> serviceFactory into that singleton and create/dispose an instance of the service wherever you need it.
using (var service = serviceFactory())
{
service.Value.UseService();
}
This is simply not possible with Autofac. All other solutions involving Autofac will require code refactoring which may potentially break software functionality. So unfortunately, the most elegant and least disruptive solution is this:
var _service = new Service(new Dependency(new context()));
Since this is an edge case addressing only one part of the software, this compromise is acceptable. It would be nice, however, if Autofac implemented this functionality in some future release.

Logging as a decorator vs. Dependency Injection - what if I need to log inside the class?

(I originally asked this question in this comment, but Mark Seemann asked me to create a new question instead.)
I'm starting a new app (.NET Core, if that matters), and right now I'm trying to decide how exactly to do logging.
The general consensus seems to be that logging is a cross-cutting concern, so the logger shouldn't be injected directly into the class that is supposed to log.
Often, there's an example like the following class how not to do it:
public class BadExample : IExample
{
private readonly ILogger logger;
public BadExample(ILogger logger)
{
this.logger = logger;
}
public void DoStuff()
{
try
{
// do the important stuff here
}
catch (Exception e)
{
this.logger.Error(e.ToString());
}
}
}
Instead, the class with the business logic shouldn't know about the logger (SRP) and there should be a separate class which does the logging:
public class BetterExample : IExample
{
public void DoStuff()
{
// do the important stuff here
}
}
public class LoggingBetterExample : IExample
{
private readonly IExample betterExample;
private readonly ILogger logger;
public LoggingBetterExample(IExample betterExample, ILogger logger)
{
this.betterExample = betterExample;
this.logger = logger;
}
public void DoStuff()
{
try
{
this.betterExample.DoStuff();
}
catch (Exception e)
{
this.logger.Error(e.ToString());
}
}
}
Whenever an IExample is needed, the DI container returns an instance of LoggingBetterExample, which uses BetterExample (which contains the actual business logic) under the hood.
Some sources for this approach:
Blog posts by Mark Seemann:
Instrumentation with Decorators and Interceptors
Dependency Injection is Loose Coupling
Blog post and SO answer by Steven:
Meanwhile... on the command side of my architecture
Windsor - pulling Transient objects from the container
My question:
Obviously, the LoggingBetterExample approach only works as long as the logging can be done outside the actual class.
(like in the example above: catch any exceptions thrown by BetterExample from outside)
My problem is that I'd like to log other things inside the actual class.
Mark Seemann suspected here that if someone needs to do this, maybe the method in question is doing too much.
As I said before, I'm in the planning phase for a new application, so I don't have much code to show, but the use case I'm thinking right now is something like this:
My app will have a config file with some optional values.
The user may decide to omit the optional values, but it's an important decision to do this.
So I'd like to log a warning when some of the optional values are missing, just in case it happened by error.
(omitting the values is perfectly fine though, so I can't just throw an exception and stop)
This means that I will have a class which reads config values and needs to do something like this (pseudocode):
var config = ReadConfigValues("path/to/config.file");
if (config.OptionalValue == null)
{
logger.Warn("Optional value not set!");
}
No matter if ReadConfigValues is in this class or a different one, I don't think this class would violate the SRP.
When I'm not able to log outside the actual class by using a decorator, is there a better solution than to inject the logger?
I know I could read the config file in the inner class, but check the values (and log the warning) in the decorator. But IMO checking the value is business logic and not infrastructure, so to me it belongs in the same class where the config file is read.
checking the value is business logic and not intfastructure, so to me it belongs in the same class where the config file is read.
Obviously, I don't know your domain well enough to dispute the truth of that assertion, but that logging is part of the domain model sounds strange to me. Anyway, for the sake of argument, let's assume that this is the case.
What ought not to be the case, though, is that reading a configuration file is domain logic. While reading and manipulating the data from a file could easily be domain logic, reading a file is I/O.
The most common approach to Inversion of Control in application architecture is to employ the Ports & Adapters architecture. The entire point of such an architecture is to decouple the domain model from I/O, and other sources of non-determinism. The poster example is to show how to decouple the domain model from its database access, but file access falls squarely in that category as well.
What this ought to imply in this particular case is that you're going to need some IConfigurationReader interface anyway. This means that you can apply a Decorator:
public class ValidatingConfigurationReader : IConfigurationReader
{
private readonly IConfigurationReader reader;
private readonly ILogger logger;
public ValidatingConfigurationReader(IConfigurationReader reader, ILogger logger)
{
this.reader = reader;
this.logger = logger;
}
public MyConfiguration ReadConfigValues(string filePath)
{
var config = this.reader.ReadConfigValues(filePath);
if (config.OptionalValue == null)
{
this.logger.Warn("Optional value not set!");
}
return config;
}
}
This ValidatingConfigurationReader class can be implemented in the domain model, even if the underlying, file-reading IConfigurationReader implementation belongs in some I/O layer.
Don't take SRP so seriously, otherwise you'll end up with functional programming. If you afraid of getting your class cluttered by putting log statements inside it, then you have two options. The first one you already mentioned which is using a Decorator class but you can't access/log the private stuff. The second option is using partial classes and putting the logging statements in a separate class.

What really interceptors do with my c# class?

I was asked to implement castle dynamic proxy in my asp.net web application and i was going through couple of articles which i got from Castle Project and Code Project about castle dynamic proxy in asp.net web application....
Both articles delt with creating interceptors but i can't get the idea why interceptors are used with classes.... Why should i intercept my class which is behaving properly?
Let's say that your class needs to do 3 things for a certain operation:
Perform a security check;
Log the method call;
Cache the result.
Let's further assume that your class doesn't know anything about the specific way you've configured your security, logging, or caching. You need to depend on abstractions of these things.
There are a few ways to go about it. One way would be to set up a bunch of interfaces and use constructor injection:
public class OrderService : IOrderService
{
private readonly IAuthorizationService auth;
private readonly ILogger logger;
private readonly ICache cache;
public OrderService(IAuthorizationService auth, ILogger logger,
ICache cache)
{
if (auth == null)
throw new ArgumentNullException("auth");
if (logger == null)
throw new ArgumentNullException("logger");
if (cache == null)
throw new ArgumentNullException("cache");
this.auth = auth;
this.logger = logger;
this.cache = cache;
}
public Order GetOrder(int orderID)
{
auth.AssertPermission("GetOrder");
logger.LogInfo("GetOrder:{0}", orderID);
string cacheKey = string.Format("GetOrder-{0}", orderID);
if (cache.Contains(cacheKey))
return (Order)cache[cacheKey];
Order order = LookupOrderInDatabase(orderID);
cache[cacheKey] = order;
return order;
}
}
This isn't horrible code, but think of the problems we're introducing:
The OrderService class can't function without all three dependencies. If we want to make it so it can, we need to start peppering the code with null checks everywhere.
We're writing a ton of extra code to perform a relatively simple operation (looking up an order).
All this boilerplate code has to be repeated in every method, making for a very large, ugly, bug-prone implementation.
Here's a class which is much easier to maintain:
public class OrderService : IOrderService
{
[Authorize]
[Log]
[Cache("GetOrder-{0}")]
public virtual Order GetOrder(int orderID)
{
return LookupOrderInDatabase(orderID);
}
}
In Aspect Oriented Programming, these attributes are called Join Points, the complete set of which is called a Point Cut.
Instead of actually writing dependency code, over and over again, we leave "hints" that some additional operations are supposed to be performed for this method.
Of course, these attributes have to get turned into code sometime, but you can defer that all the way up to your main application code, by creating a proxy for the OrderService (note that the GetOrder method has been made virtual because it needs to be overridden for the service), and intercepting the GetOrder method.
Writing the interceptor might be as simple as this:
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (Attribute.IsDefined(invocation.Method, typeof(LogAttribute))
{
Console.Writeline("Method called: "+ invocation.Method.Name);
}
invocation.Proceed();
}
}
And creating the proxy would be:
var generator = new ProxyGenerator();
var orderService = (IOrderService)generator.CreateClassProxy(typeof(OrderService),
new LoggingInterceptor());
This is not only a lot less repetitive code, but it completely removes the actual dependency, because look what we've done - we don't even have an authorization or caching system yet, but the system still runs. We can just insert the authorization and caching logic later by registering another interceptor and checking for AuthorizeAttribute or CacheAttribute.
Hopefully this explains the "why."
Sidebar: As Krzysztof Koźmic comments, it's not a DP "best practice" to use a dynamic interceptor like this. In production code, you don't want to have the interceptor running for unnecessary methods, so use an IInterceptorSelector instead.
The reason you would use Castle-DynamicProxy is for what's called Aspect Orientated Programming. It lets you interject code into the standard operation flow of your code without the need to become dependent on the code itself.
A simple example is as always, logging. That you would create a DynamicProxy around a class that you have errors from that it logs the data going into the method and catches any exceptions and then logs the exception.
Using the intercepter your current code has no idea it exists (assuming you have your software built in a decoupled way with interfaces correctly) and you can change the registration of your classes with an inversion of control container to use the proxied class instead without having to change a single line else where in code. Then when you solve the bug you can turn off the proxying.
More advanced usage of proxying can be seen with NHibernate where all of the lazy loading is handled through proxies.

Categories