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.
Related
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());
My application uses autofac IoC. It contains a layer that establishes connections to external applications (creating "Protocol" objects) - Therefore, I realized from my previous question that I should use autofac factory:
Autofac resolve in deep layer
I have a side project that includes all the autofac nugets and dlls. This one provides specific API which I use to register types in my application:
RegisterType
RegisterTypeAndAutowireProperties
RegisterConfigurationObject
RegisterInstance
BuildContainer
UpdateContainer
I believe this API is generic and fits for any application that will want to make use of IoC container.
My problem is with the factories. For example in my current application I need a factory for protocols (which are keyed and depend on many keyed services as well). Each protocol object is taking different kind and number of services and therefore I don't have a way other than making an explicit method for each protocol registration if I'm correct.
Now what happens in the next application that'll want to use this IoC API? It might not have the protocols this application contains, a case which will force me to update the IoC API for each application. Is there a way to keep my IoC wrapper generic - make it fit for any application no matter that types it contains? If you have any ideas in mind please share them with me!
Thank you
Edit:
I'll try to make it clearer, I use Autofac only. This "wrapper" is a project with the references to autofac that supplies basic API of IoC. For now I use this project only in application1.
But If tomorrow I start developing application2 I want to use this same wrapper. Therefore I can't have factories in my wrapper project that fit for a specific application. This is my issue
I need to fetch data from an external API, only accessible via VPN.
The development/test machine will not always be able to connect to the VPN.
The desired behaviour is to use two different implementations (one that calls the actual external API and one that acts as the real thing but returns dummy data). Which implementation to use will be configured via a flag in web.config
I've tried the IoC containers StructureMap and Unity and they both did the job but they only seem to be applicable for MVC, I'm looking for a generic solution that also works for web forms. And also, isn't it a bit overkill to use them for this isolated design problem!?
Is there a design pattern or best practice approach for this particular scenario?
IoC / dependency injection sounds like the correct approach, but you don't necessarily need a container for a simple scenario. The key is to have classes that depend on the API reference an interface IAPI, and pass it the actual implementation RealAPI or FakeAPI.
public class SomeClass
{
private readonly IAPI _api;
public SomeClass(IAPI api)
{
_api = api;
}
}
Now you should be able to switch out the implementation easily by passing a different object to MyClass. In theory, when you're using an IoC approach, you should only need to bind the interface to the implementation once, at the top level of the application.
isn't it a bit overkill to use them for this isolated design problem!?
They probably are. Those IoC containers only help you when you wrote loosly coupled code. If you didn't design your classes according to the SOLID principles for instance, those frameworks will probably only be in the way. On the other hand, which developer doesn't want to write loosly coupled code? In other words, IoC container solves a problem you might not have but it's a nice problem to have.
StructureMap and Unity [...] only seem to be applicable for MVC
Those ioc frameworks can be used in any type of application (as long as it is written in loosly coupled way). Some types of applications need a bit more work to plug a framework in, but it's always possible. StructureMap and Unity might only have integration packages for MVC, it's quite easy to use them in ASP.NET Web Forms as well.
Is there a design pattern or best practice approach for this
particular scenario?
What you're looking for is the Proxy pattern and perhaps the circuit breaker pattern.
Is the IServiceProvider basically just a generic interface for any IOC container, or is it used for a specific framework? I'm rolling my own light weight IOC container and I am wanting to know if I should implement it. Are there any other interfaces that I should implement? I'm not really interested in either MEF or Unity. I've used both extensively and they don't really work for my current project.
IServiceProvider is an imported (or perhaps held-over) COM interface that is intended to be used for private features in the context of the object whom you interrogate for a Service. The term 'Service' is applied rather loosely here, it originally meant any COM object that could be returned based upon what GUID is given.
IServiceProvider # MSDN (.NET reference)
IServiceProviderImpl Class # MSDN (C++ ATL reference)
In .NET, you don't need to implement it unless you have a client that specifically supports it, and in many cases you won't need to add yet another level of indirection that is implied by using IServiceProvider. Also, you can devise your own scheme to share common objects or implement other use patterns based upon IoC / Dependency Injection that are more flexible or more rigid as dictated by your needs.
One good historical context for IServiceProvider is the IE Browser Plugin Spec. Here, it is used to allow plugin components to use Browser Host features in-context. In a COM context, this interface is useful because it hides the details of instantiation and also can be used as part of a object construction and utilization strategy to avoid reference loops.
WebBrowser Customization (Part 2) # MSDN
I think it is a pretty general use interface, so you can use it with anything. It almost should not even be in the Framework Class Library. For one specific use, Alex D. James of the WCF Data Services team has a blog about it.
http://blogs.msdn.com/b/alexj/archive/2010/01/07/creating-a-data-service-provider-part-2-iserviceprovider-datasources.aspx
I do not think it has anything to do with IoC containers. I have used Unity and Autofac quite a bit and have never seen it used with either. As for rolling your own, I would suggest you define your own container interface in the more standard generic way:
public interface IContainer
{
T Resolve<T>();
}
That is pretty standard with some variation, but you could also just use IServiceProvider if that fits your needs.
And on that note, unless this is just an academic exercise, you might want to read "Dependency Injection". Mark Seemann covers every container out there and quite a bit of theory and practice. That is, I highly recommend it.
https://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/
ASP.NET 5 uses IServiceProvider in "self-hosted" mode, that is, when hosting an ASP.NET application and the runtime in a console application or service.
(An object of type Microsoft.Framework.Runtime.Common.DependencyInjection.ServiceProvider -- which implements IServiceProvider -- is passed to your console app constructor.)
Thus, if you wanted to use a different IoC container in ASP.NET 5, you might want to implement this interface. Or wrap the other IoC container in a class which implements this interface.
The new (as of .NET 4) Runtime Caching API also uses it: http://msdn.microsoft.com/en-us/library/system.runtime.caching.objectcache.host.aspx.
And also Visual Studio designer.
I'm building a CMS and it has many extension points (Data/ContentTypes, Plugins, Macros, Themes) and some of those extensions need to register services. So far extensions only depend on 'MyProject.Core' library and it would be nice if they wouldn't be dependant on any specific IoC framework. Now I'm thinking if I should build another layer to hide IoC specific registrations. The problem is that I need some advanced functionality.
E.g. NHibernate implementation of 'Data/ContentType' services (Castle Windsor style)
container.Register(Component.For<IPageRepository>().ImplementedBy<NHPageRepository>());
container.Register(Component.For<ISessionFactory>().Instance(NHibernateHelper.CreateSessionFactory()));
container.Register(Component.For<ISession>().UsingFactoryMethod(c => c.Resolve<ISessionFactory>().OpenSession()).LifeStyle.PerWebRequest);
Third line is the "hard one". I could make an interface like
interface IMyContainer
{
Register<TService>(Func<IMyContainer,TService> factoryMethod)
Register<TService>(Func<IMyContainer,TService> factoryMethod, LifeStyle lifeStyle)
// ...
}
but "translating" this registration (my IoC abstraction)
public class NHInstaller : IInstaller
{
public void Install(IMyContainer container)
{
container.Register<ISession>(c => c.Resolve<ISessionFactory>().OpenSession(), LifeStyle.PerRequest);
}
}
to this (Windsor)
container.Register(Component.For<ISession>().UsingFactoryMethod(c => c.Resolve<ISessionFactory>().OpenSession()).LifeStyle.PerWebRequest);
could be quite hard.
So, should I try to make that abstraction? Any helpful resources?
Or should I just pick a IoC container and stick with it?
I could also make source code of an existing tool (Castle Windsor or Ninject) a part of my library, but I don't really understand those licenses. Can I do that? Can I change namespaces and class names to fit the structure of my app? I'm going to release the source code and I don't really care what the license is going to be.
It depends on what you mean by "hide." Best practice is that only one place in your application (the Composition Root) knows about the IoC container. Stick to the Hollywood Principle - avoid having multiple classes that know about the IoC container. In other words don't pass the container around; if a non-root class needs to create other objects then inject a factory into it.
If you're writing a framework and want to allow consumers to plug in their IoC container framework of choice, you could use the Common Service Locator library. That is likely overkill for most projects. (See Mark Seemann's excellent link for the reason I changed the wording).
Short answer - no, the abstraction is useless, you'd be wasting your employer's money. Use Installers to partition the registration instead.