add new object in IOC container without having to specify every consturctor param - dependency-injection

I'm trying to add a class to my scoped service in .net core 2.1, I don't want a provider to get all the services needed to satisfy the params of the constructor. Is there an easier way to do this?
services.AddScoped<BarcodePage>((provider) =>
new BarcodePage(provider.GetService<IObservationRepository>(),
provider.GetService<IPageFactory>(),
provider.GetService<IMediator>(),
provider.GetService<IUserRepository>()));

You could just register it as
services.AddScoped<BarcodePage>();
The container will resolve the BarcodePage class dependencies for you.

Related

MVC Dependency resolver conditional

I am using dependency resolver and i have added my unity container to the same. So by default "GoldCustomer" gets injected in to the "CustomerController" as per the current container rules.
IUnityContainer oContainer = new UnityContainer();
oContainer.RegisterType<ICustomer, GoldCustomer>(); // injects GoldCustomer
DependencyResolver.SetResolver(new UnityDependencyResolver(oContainer));
If i want to change by current container configuration i can always create new Container and set it and call the SetResolver again. I know that the above code should be configurable via XML config but still if we need to pickup new container objects we have to still call the setresolver.
Is this the right way or are there better ways of changing container depedency rules while the application running.
Second what are the events where we can change the container is it session_start , httphandler's or something better.
Firstly why would you need multiple containers? It must be the singleton object who keeps all the dependency registered since the application started.
In a practice I would say keep single container and if required create multiple Registration function in separate assemblies and invoke all of them in a AppBootstrapper.
If it's an application then best way is to use the Application start with Async behaviour so that the startup doesn't get affected.
======================================================
Unfortunately the Named registration is the only option and Unity required to register with names explicitly. Thats why I personally like DI containers like Autofac and SimpleInjector. They are fast and They allow multiple registrations of an Interface with multiple Types and the resolver uses Type resolver and Named resolver methods without explicitly asking for Names and those resolvers are overridable too.
I am not sure why it does not look that complex to me , If I understand question quickly I can do it as follows,
assume that I have interface IMovieRepository and two classes implementing it EnglishMovieRepository and HindiMovieRepository.
How about resolving them as in UnityConfig.cs as follows,
If(condition)
{
container.RegisterType<IMovieRepository, EnglishMovieRepository>();
}
else
{
container.RegisterType<IMovieRepository, HindiMovieRepository>();
}
If requirement is something different then please let me know
Thanks
/dj

Configuring structuremap to create an instance using a factory class

I want to configure structuremap to create a service using a factory class. The factory itself has a dependency that needs filling. Currently I have the following in my Registry class:
For<IDoStuffWebService>().Singleton().Use(() =>
new DoStuffWebServiceClientFactory(new ConfigProvider()).Create()
);
Rather than having to hard-code the concrete type DoStuffWebServiceClientFactory and manually fill it's dependency, I want structuremap to get this for me (it implements IDoStuffWebServiceClientFactory). It looks like IContext might help (http://docs.structuremap.net/UsingSessionContext.htm), but I'm struggling to figure out how this fits.
Any help greatly appreciated.
Roger.
To use the structuremap context in a Use method you can use the overload method that have a context as a parameter.
For<IDoStuffWebService>().Singleton().Use(ctx => ctx.GetInstance<IDoStuffWebServiceClientFactory>().Create());

Funq usage in ServiceStack

How can I access Container instance out of controller?
I have to use Container.Resolve in my class but how can I access Container instance?
Is it singleton?
Can I use new Container() or is there any chain like Funq.StaticContainer?
Thanks to Mythz for gist hint, a) or b) or c).
I will use Mythz's solution, it is accepted by me but there are concerns for it's pattern (ServiceLocator Pattern), you can check here for extra info.
There are a couple of ways to statically reference your AppHost instance. You can resolve a dependency via the IAppHost instance with:
HostContext.TryResolve<T>();
HostContext.Resolve<T>();
HostContext.AppHost.TryResolve<T>();
If for some reason you need to access the concrete Funq.Container, you can access it via the singleton:
ServiceStackHost.Instance.Container
Whilst inside a Service, Razor View Page, etc you can use:
base.TryResolve<T>();

Autofac - Inject properties into a asp.net mvc controller

I have a base controller from which inherit all my controllers. This base controller has some properties I'd like to inject the using property injection.
My controller registration looks like this
builder.RegisterControllers(Assembly.GetExecutingAssembly()
I don't know how to access the base class and inject the properties.
This should work:
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
Some more info on the autofac website: http://code.google.com/p/autofac/wiki/PropertyInjection
You may want to consider using an Autofac Aggregate Service:
An aggregate service is useful when you need to treat a set of dependencies as one dependency. When a class depends on several constructor-injected services, or have several property-injected services, moving those services into a separate class yields a simpler API.
An example is super- and subclasses where the superclass have one or more constructor-injected dependencies. The subclasses must usually inherit these dependencies, even though they might only be useful to the superclass. With an aggregate service, the superclass constructor parameters can be collapsed into one parameter, reducing the repetitiveness in subclasses. Another important side effect is that subclasses are now insulated against changes in the superclass dependencies, introducing a new dependency in the superclass means only changing the aggregate service definition.
This works for me:
using Autofac;
using Autofac.Integration.Web;
using Autofac.Integration.Web.Mvc;
builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();
builder.RegisterControllers(Assembly.GetExecutingAssembly()).InjectActionInvoker();
nickvane's answer is correct. Just make sure
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
is after your all dependencies are registered. Or in other words, just right before you build your container.
So final code will look like
.
.
.
builder.RegisterControllers(typeof(MvcApplication).Assembly).PropertiesAutowired();
var container = builder.Build();
Need to call also for MVC:
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
For Web API:
HttpConfiguration config = GlobalConfiguration.Configuration;
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

Castle Windsor equivalent of StructureMap ObjectFactory.With<>().GetInstance<>()

With StructureMap one can do a resolution and force the container to use specific dependency instance provided at the time of resolution like so:
ObjectFactory.With<ISomeDependency>(someDepedencyInstance).GetInstance<IServiceType>()
Provided instance will be used in whole resolution chain, that is not only as a direct dependency of IServiceType implementation but also as a dependency of any direct and indirect dependencies of IServiceType implementation.
How do I do something like that in Castle Windsor?
I know I can provide a direct dependency with an overload of IWindsorContainer.Resolve<>(), but I need to provide this dependency to something deeper.
You could use a named component and service overrides:
var container = new WindsorContainer();
container.Register(Component.For<ISomeDependency>()
.ImplementedBy<SomeDependency>());
container.Register(Component.For<ISomeDependency>()
.ImplementedBy<SomeOtherDependency>()
.Named("other"));
container.Register(Component.For<IService>()
.ImplementedBy<Service>()
.ServiceOverrides(ServiceOverride.ForKey("dep").Eq("other")));
See this article for more information on service overrides.
You can register an instance as the implementation of a given component like this:
container.Register(Component
.For<ISomeDependency>()
.Instance(someDependencyInstance));
This means that everytime you resolve anything and ISomeDependency is part of the resolved object graph, the someDependencyInstance instance will be used.
It that what you want, or did I misunderstand the question?
Based on additional information, here's a new attempt at answering the question.
You should be able to use container hierarchies for this. If a Windsor container can't resolve a type, it'll ask its parent. This means that you can create a child container that contains only the override and then ask that container to resolve the type for you.
Here's an example:
var container = new WindsorContainer();
container.Register(Component
.For<ISomeDependency>()
.ImplementedBy<SomeDependency>());
container.Register(Component
.For<IService>()
.ImplementedBy<Service>());
var childContainer = new WindsorContainer();
childContainer.Register(Component
.For<ISomeDependency>()
.ImplementedBy<SomeOtherDependency>());
childContainer.Parent = container;
var service = childContainer.Resolve<IService>();
The resolved service will contain an instance of SomeOtherDependency and not SomeDependency.
Notice how childContainer only overrides the registration of ISomeDependency. All other registrations are used from the parent.

Resources