How to avoid Services.AddScoped for every Use Case I have? - c#

I'm trying to learn asp.net core (3.1) and clean architecture at the same time. The GitHub repository which I'm using as base is the https://github.com/ivanpaulovich/clean-architecture-manga and it's great.
The approaches used are pretty good and the repo owner answers you about the reasons of each approach.
The problem I found is not about the approach now, but a better resolution.
The webapi\dependencyinjection\ApplicationExtensions.cs class adds a scope for every use case he has:
services.AddScoped<Application.Boundaries.CloseAccount.IUseCase, Application.UseCases.CloseAccount>();
services.AddScoped<Application.Boundaries.Deposit.IUseCase, Application.UseCases.Deposit>();
services.AddScoped<Application.Boundaries.GetAccountDetails.IUseCase, Application.UseCases.GetAccountDetails>();
services.AddScoped<Application.Boundaries.GetCustomerDetails.IUseCase, Application.UseCases.GetCustomerDetails>();
services.AddScoped<Application.Boundaries.Register.IUseCase, Application.UseCases.Register>();
services.AddScoped<Application.Boundaries.Withdraw.IUseCase, Application.UseCases.Withdraw>();
services.AddScoped<Application.Boundaries.Transfer.IUseCase, Application.UseCases.Transfer>();
There is any way to make it generic? To resolve the sample code with one line code only and all the use cases created after it will be injected?

Explicitly registering dependencies can be seen as a benefit because you won’t get unwanted surprises later at runtime from seemingly “magic” registrations. This is especially true since your convention to register these types appears to be solely based on interface naming or namespaces. I would recommend you to add some stronger identifiers (e.g. common interfaces, or marker interfaces) if you want to utilize a convention-based registration there. Otherwise, it may seem better to list every single DI registration even if that may seem very verbose.
That being said, there are utilities that will help you with convention-based registrations. Of course, you could always write some code using reflection to register such things automatically. There is also this very useful utility package Scrutor that will register types based on conventions for you.
If each of the type only implements a single interface, then you could use the following scan to register the services as scoped services for their interfaces:
var type = typeof(Application.UseCases.CloseAccount);
services.Scan(scan => scan.FromAssembliesOf(type)
.AddClasses(classes => classes.InExactNamespaceOf(type))
.AsImplementedInterfaces()
.WithScopedLifetime());

Related

Reflection vs reference - IoC container registering

I have some IoC container (it doesn't matter which one, but lets assume it is Autofac). In my solution I have more than 30 services which need to be registered. All services resides in the same assembly called Services and each class has a name in format {specific_name}Service.cs.
I'd like to avoid for some reasons registering each service manually this way:
container.Register<OneService>().AsSelf();
container.Register<TwoService>().AsSelf();
...
container.Register<ThirtyFourService>().AsSelf();
And register my types in this way:
Type[] serviceTypes = Assembly.Load("Services")
.GetTypes()
.Where(t => t.Name.EndsWith("Service"))
.ToList();
foreach(Type serviceType in serviceTypes)
{
container.Register(serviceType).AsSelf();
}
All I want achive is minimalistic registration process which allows me add or remove services and keep source code clean. Initialization of my application can be slow (server side application), but when first request comes, it has to behave as quick as possible (performance does really matter at serving responses). Saying initialization I mean registering types, reading configuration files, etc.
Does such reflection usage slow my application "at runtime" or just impact app initialization? How dependencies will be resolved later?
Assuming you do registration once there will be no impact on requests - both ways of registering (.Register<TwoService>().AsSelf() and essentially .Register(typeof(TwoService)).AsSelf()) should do exactly the same thing. You can check yourself for container of your choice that one simply calls another.
Note that depending on container you use there could be existing way to register "all types matching pattern". I.e. Unity already "registers" all types - so there in no need for Register<ConcreteType>() at all.
In AutoFac, there are two ways to control the lifetime of your request: InstancePerHttpRequest or InstancePerApiRequest.
But, If you use InstancePerHttpRequest or InstancePerApiRequest it will be basically the same thing, you will need to parser for all Services of your class and register them. I don't think that it will be to more expensive for your application, because some extensions are doing the same thing. E.g. AutoFac like AutoFac for MVC 5 or Autofac for web Api.
So, if you are not concerned about few milliseconds of performance, you can go for it.
I would imagine it is still using Activator.CreateInstance for each of the services, so there is a minor hit there, as well as the obvious reflection discovery service. I don't think you have anything to worry about performance wise from the container perspective. If for some reason you do run into issues, check another container for better performance as this is a common use case and should be supported quite well and widely.

C#, Unity IoC: Registering and resolving generic interfaces, good practices

I wrote generic interface and over time, I started using it quite often. I had also idea to actually provide another generic interface, extending existing one.
Now, when I look into my Unity config (IoC framework is irrelevant here), it looks like this:
container.RegisterType<IConfigProvider<ICountryConfig>, CountryConfigProvider>();
container.RegisterType<IConfigProvider<ILanguageConfig>, LanguageConfigProvider>();
// IEnumerableConfigProvider<T> : IConfigProvider<IEnumerable<T>>
container.RegisterType<IEnumerableConfigProvider<ILocaleConfig>, LocaleConfigProvider>();
// ... repeat gazillion of times...
Using as dependency:
public LocaleResolver(IConfigProvider<ICountryConfig> countryConfigProvider, ...)
{
// similar construct all over the place
}
Where ICountryConfig, ILanguageConfig, ... are interfaces describing database entities. Provider then takes care to provide correct entities to dependent components so access to storage is kept on own place.
Problem arise when I did little refactoring. I used accidentally parent interface instead of inherited one. It could be also quite fragile when using wrong type given to interface.
This led me to (obvious) idea creating yet another layer of interfaces to encapsulate concrete usage. That would solve issues described above, in other hand I will end up with trillion empty interfaces for every possible implementation.
// ICountryConfigProvider : IConfigProvider<ICountryConfig>
container.RegisterType<ICountryConfigProvider, CountryConfigProvider>();
// ILanguageConfigProvider : IConfigProvider<ILanguageConfig>
container.RegisterType<ILanguageConfigProvider, LanguageConfigProvider>();
// ILocaleConfigProvider : IEnumerableConfigProvider<ILocaleConfig>
container.RegisterType<ILocaleConfigProvider, LocaleConfigProvider>();
And it's cleaner usage:
public LocaleResolver(ICountryConfigProvider countryConfigProvider, ...)
{
// ...
}
And what I'm looking for now is a good advice. Maybe I'm abusing IoC too much here. What is the best approach for mid-size project?
I'm aware this topic might end up with discussion rather than specific answer, I apologize for that dear StackOverflow.
If each provider is a different concrete type then this approach, albeit verbose with the empty interfaces, is valid. Another, less verbose, solution would be generalise the configuration access so instead you have a single configuration 'service' that returns any one of many specific config blobs.
Eg configProvider.GetConfig<IWhateverConfig>();
This way you aren't flooding the container with lots of providers for what is essentially just retrieval of a certain type of property bag full of config. You would register a single config provider and under the covers map the config type to a config section. If you exposed this mapping functionality then config blobs can be registered in a more modular way at any point during application start up.

Orchard CMS - Preferred method for feature switching when not using IDependency

I want to feature switch a service implementation. This is easy to do by making Interfaces inherit IDependency and simply marking implementation with:
[OrchardFeature("MyFeature")]
[OrchardSuppressDependency("MyService1")]
There are a couple of reasons I can't use IDependency for this:
I need to inject a named service into my implementations
Interceptors need to be used with the services
Therefore, the implementations need to have an explicit autofac registration. To feature switch, I need to create 2 autofac registration modules and feature switch them.
My question is: Is this the preferred method? Is there another way that you can suggest to feature switch these autofac registrations?
Custom Autofac module is indeed the preferred way in case you need to do more complex registrations (like named or intercepted ones etc.). We use those a lot in Orchard core.
Autofac module in Orchard can be the subject to OrchardFeature as well as OrchardSuppressDependency attributes, making it a pretty powerful and easy to use solution when customization is required.

Autofac: Resolving an IEnumerable of registrations on the same name

I am using Autofac to handle dependency injection in my application. In order not to have to do every single registration explicitly, I first use RegisterAssemblyTypes().AsImplementedInterfaces() and then only take care of those that need to be specially configured.
I have an interface called IToolStripPopulator that has a few different implementations, several of which are in use, but some aren't anymore (as I'm trying to work SOLIDly and adhere to OCP, I am usually not changing them if I need different functionality, but rather leave them alone and create new ones that do what I need now). For that reason I need to overwrite the automatic registration for the interface, in two ways:
One implementation is to be injected into my main logic and acts as a decorator for a few of the others. I naturally want this to be registered via As<IToolStripPopulator>() and be done with it as this is the implementation my application's functionality currently depends on.
Those other implementations are the "inner" populators only to be used within that decorator class. To inject them, there are two ways:
Explicitly wiring up the constructor for the outer implementation with the specific types; this is not very nice, also because that constructor would have to take the exact number of inner populators I am using right now, which is not OCP compliant.
Have the outer implementation take an IEnumerable<IToolStripPopulator>; this is what I'd like to do, but it's also where I'm stuck.
I can't let Autofac resolve that IEnumerable on its own, because it would just resolve all implementations of the interface, even those that I'm not using anymore as well as the "outer" that I don't want in there (and which would probably cause an endless loop during resolution).
So what I'd like to do is this:
// the inner populators
builder.RegisterType<BrowsersMenuPopulator>().Named<IToolStripPopulator>("inner");
builder.RegisterType<ThreadsafeConnectionMenuPopulator>().Named<IToolStripPopulator>("inner");
// the decorator implementation
builder.RegisterType<BrowserAndConnectionMenuPopulator>().As<IToolStripPopulator>().WithParameter( ? );
But there is no way to actually access the existing registrations at that point.
....and here I tried just one more thing which I didn't actually expect to work, but it did.
builder.Register(c => c.ResolveNamed<IEnumerable<IToolStripPopulator>>("inner")).As<IEnumerable<IToolStripPopulator>>();
does not, as I would have expected, try to resolve an IEnumerable<IToolStripPopulator> registration named "inner", but an IEnumerable of IToolStripPopulator registrations named "inner" - exactly as I need it.
This will then correctly be resolved and injected into the decorator implementation just from having that registered As<IToolStripPopulator>() with no further configuration.
From a formal aspect I would actually have preferred being able to state the name by which to resolve directly with the decorator registration because that would be more intuitive and flexible (what if I need to resolve several IEnumerable<IToolStripPopulator>?), but in many cases this should be enough.
#codinghorror's concept of "rubber duck problem solving" rules my every workday....
The only way to directly specify that I know of is to "new-up" directly in your registration code:
//decorator impl
builder.Register(c => new BrowserAndConnectionMenuPopulator(c.ResolveNamed<IEnumerable<IToolStripPopulator>>("inner"),...)).As<IToolStripPopulator>();
This has the advantage of specifying directly in the registration the exact required dependencies, but the disadvatage of loss of flexibility in reconfiguring BrowserAndConnectionMenuPopulator's dependencies. I included this for completeness, but honestly I prefer the solution you discovered.

Does Dependency Injection (DI) rely on Interfaces?

This may seem obvious to most people, but I'm just trying to confirm that Dependency Injection (DI) relies on the use of Interfaces.
More specifically, in the case of a class which has a certain Interface as a parameter in its constructor or a certain Interface defined as a property (aka. Setter), the DI framework can hand over an instance of a concrete class to satisfy the needs of that Interface in that class. (Apologies if this description is not clear. I'm having trouble describing this properly because the terminology/concepts are still somewhat new to me.)
The reason I ask is that I currently have a class that has a dependency of sorts. Not so much an object dependency, but a URL. The class looks like this [C#]:
using System.Web.Services.Protocols;
public partial class SomeLibraryService : SoapHttpClientProtocol
{
public SomeLibraryService()
{
this.Url = "http://MyDomainName.com:8080/library-service/jse";
}
}
The SoapHttpClientProtocol class has a Public property called Url (which is a plain old "string") and the constructor here initializes it to a hard-coded value.
Could I possibly use a DI framework to inject a different value at construction? I'm thinking not since this.Url isn't any sort of Interface; it's a String.
[Incidentally, the code above was "auto-generated by wsdl", according to the comments in the code I'm working with. So I don't particularly want to change this code, although I don't see myself re-generating it either. So maybe changing this code is fine.]
I could see myself making an alternate constructor that takes a string as a parameter and initializes this.Url that way, but I'm not sure that's the correct approach regarding keeping loosely coupled separation of concerns. (SoC)
Any advice for this situation?
DI really just means a class wont construct it's external dependencies and will not manage the lifetime of those dependencies. Dependencies can be injected either via constructor, or via method parameter. Interfaces or abstract types are common to clarify the contract the consumer expects from its dependency, however simple types can be injected as well in some cases.
For example, a class in a library might call HttpContext.Current internally, which makes arbitrary assumptions about the application the code will be hosted in. An DI version of the library method would expect a HttpContext instance to be injected via parameter, etc.
It's not required to use interfaces -- you could use concrete types or abstract base classes. But many of the advantages of DI (such as being able to change an implementation of a dependancy) come when using interfaces.
Castle Windsor (the DI framework I know best), allows you to map objects in the IoC container to Interfaces, or to just names, which would work in your case.
Dependency Injection is a way of organizing your code. Maybe some of your confusion comes from the fact that there is not one official way to do it. It can be achieved using "regular" c# code , or by using a framework like Castle Windsor. Sometimes (often?) this involves using interfaces. No matter how it is achieved, the big picture goal of DI is usually to make your code easier to test and easier to modify later on.
If you were to inject the URL in your example via a constructor, that could be considered "manual" DI. The Wikipedia article on DI has more examples of manual vs framework DI.
I would like to answer with a focus on using interfaces in .NET applications. Polymorphism in .NET can be achieved through virtual or abstract methods, or interfaces.
In all cases, there is a method signature with no implementation at all or an implementation that can be overridden.
The 'contract' of a function (or even a property) is defined but how the method is implemented, the logical guts of the method can be different at runtime, determined by which subclass is instantiated and passed-in to the method or constructor, or set on a property (the act of 'injection').
The official .NET type design guidelines advocate using abstract base classes over interfaces since they have better options for evolving them after shipping, can include convenience overloads and are better able to self-document and communicate correct usage to implementers.
However, care must be taken not to add any logic. The temptation to do so has burned people in the past so many people use interfaces - many other people use interfaces simply because that's what the programmers sitting around them do.
It's also interesting to point out that while DI itself is rarely over-used, using a framework to perform the injection is quite often over-used to the detriment of increased complexity, a chain-reaction can take place where more and more types are needed in the container even though they are never 'switched'.
IoC frameworks should be used sparingly, usually only when you need to swap out objects at runtime, according to the environment or configuration. This usually means switching major component "seams" in the application such as the repository objects used to abstract your data layer.
For me, the real power of an IoC framework is to switch implementation in places where you have no control over creation. For example, in ASP.NET MVC, the creation of the controller class is performed by the ASP.NET framework, so injecting anything is impossible. The ASP.NET framework has some hooks that IoC frameworks can use to 'get in-between' the creation process and perform their magic.
Luke

Categories