Accessing dependencies in separate thread in MVC application using Castle Windsor - asp.net-mvc

Working on an MVC application with the below architecture. Bootstrapped with Castle Windsor.
Controller -> Service -> Repository (uses DbContext).
Now certain flows in the application require that I run some part of the flow in a thread.
For example:
Controller -> service ->Repo1 -> control returns to service -> new
Thread() started-> Repo2
The issue I face is the dbcontext is disposed as it is declared as LifestylePerWebRequest().I have tried using LifestyleTransient() that didnt seem to work. What am I missing?
There are similar dependencies which i have to sometimes use in a separate thread and sometimes in a single request. How do i configure Windsor to handle these dependencies?

There is a nuget package that i use to extend the lifestyles for Castle Windsor and it is called: Castle.Windsor.Lifestyles.
It has hybrid lifestyles which are handy for web requests and threads.
container.Register
(
Classes.FromAssemblyContaining<IServiceFactory>()
.BasedOn<IServiceFactory>()
.WithServiceAllInterfaces()
.Configure(c => c.LifeStyle.HybridPerWebRequestPerThread())
);
The important functionality is HybridPerWebRequestPerThread() which creates a new instance for the initial web request and then for every new thread it will create a new instance.

Related

How to inject 3rd party IOC container into ASP.NET Core Startup class

I'm creating a web API using ASP.NET Core, and I'm using SimpleInjector as my DI framework. I understand the basics of how to use SI with ASP.NET Core; my problem is more an architectural one.
I have a project with integration tests for the API project, in order to test the raw API endpoints and responses. Naturally, the test server (set up using Microsoft.AspNetCore.TestHost) should use the API project's real Startup class.
The problem lies in where to register mocks for the controllers' dependencies, because I don't want to have all the production implementations being registered when testing: Firstly, most of them are, of course, dependencies used by the production implementations of the controller dependencies I'll be mocking in the first place; and secondly, in case I update my controllers and forget to register mocks of the new dependencies, I want my code to fail (container verification) instead of silently using production dependencies that are present in the container.
Thus, the dependencies can't be registered in the Startup class. That's fine by me – I think I'd rather keep the composition root in a separate assembly referencing all other assemblies, anyway. AFAICS the ASP.NET Core project would need to reference this project, which exposes a single method that returns a pre-registered container that can be used in the Startup class, where it's needed to register e.g. the controller activator (and will undergo final validation).
But this begs the question: How to get the container – being already registered with all my application components (whether production implementations from the composition root project, or mocks from the integration test project) – into my Startup class?
My initial solution is to simply have a static property on the Startup class called e.g. Container, and assign that before using WebHostBuilder. This seems "pragmatically robust": The application will fail fast (NullReferenceException) if it's not set before the Startup class is run, and the property is only used during setup, so I don't really need to guard against it being set multiple times or being set to null or any such thing – if it's assigned before startup, it works, if not, it won't start.
Does this seem like a solid solution, or am I oblivious to any obvious ways this will will come back to bite me later on? Are there any better solutions?

DI in .NET Core without ASP.NET Core

I'm looking to write a daemon process using .NET Core which will basically act much like a cron job and just orchestrate API/DB calls on some interval. As such, it has no need to expose any web routes, so there's no need for ASP.NET Core.
However, afaik ASP.NET Core is where you get that nice Startup class with all the DI plumbing and environment-based configuration you might need.
The way I see it, I have two options:
Forgo ASP.NET Core and just hook up the DI framework on my own. If I go that route, how do I do that?
Include ASP.NET Core just for the DI portion, but then how do I spawn background tasks which "run forever" outside of any request context? My understanding is that the DI framework very much assumes there's some sort of incoming request to orchestrate all the injections.
You seem to pose multiple questions let me try to answer them one by one.
Dependendency injection without Startup Class.
This is definitely possible. Since the Startup class is part of the WebHostBuilder package (which contains Kestrel/webserver). The Dependency injection is nuget package is just a dependency on this package and so can be used alone in the following way:
var services = new ServiceCollection();
services.AddTransient<IMyInterface, MyClass>();
var serviceProvider = services.BuildServiceProvider(); //ioc container
serviceProvider.GetService<IMyInterface>();
So at your program main (startup function) you can add this code and maybe even make the ServiceProvider Staticaly available.
Note that the IHostingEnvironment is also part of the kestrel package and not available to you, but there are simple workarounds for this.
Registration
Im not sure what exactly you mean by spawning background tasks/running forever. But in dotnet you can spawn tasks with TaskCreationOptions.LongRunning to tell the schedular that your task will be running very long and dotnet wel optimise threads for this. you can also use serviceProvider in these tasks.
The only downside to the DI is that you need to set it up at the startup of your application and cannot add new services while running your application (actually you can add to services and then rebuild the serviceProvider, but its easier using another external IOC container). If you where thinking of running some kind of plugin system where dependencies would automaticaly be registered, you're better of making your own factory method.
Also note when using plugins, when they are loaded in as dll's, they cannot be unloaded so if you have a theoretically unlimited amount of plugins, your memory will slowly build up every time you add new plugins.
As of.NET Core 2.1 this can/should be done with a Generic Host. From
.NET Core docs:
"The goal of the Generic Host is to decouple the HTTP pipeline from the Web Host API to enable a wider array of host scenarios..."
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.1
public static async Task Main(string[] args)
{
var builder = new HostBuilder()
.ConfigureAppConfiguration((hostingContext, config) =>
.ConfigureServices((hostContext, services) =>
{
// ...
});
await builder.RunConsoleAsync();
}

Unity.Mvc3 vs Unity.Mvc

Using the Unity.Mvc3 with a Mvc 3 application, i could register my IDummyService as follows:
container.RegisterType<IDummyService, DummyService>(new HierarchicalLifetimeManager());
On each web request, a new instance of my IDummyService is created (as explained in this article), but since I upgraded Mvc 3 to Mvc 4 and hense Unity.Mvc3 to Unity.Mvc, an single instance is created and used across all web requests, untill restarting the app. Basically, IDummyService is a singleton in a Mvc 4 application when using HierarchicalLifetimeManager. For me this is hard to believe this is intended new behavior in Unity.Mvc.
Is there a better explanations for this?
Unity.Mvc3 and Unity.Mvc are created by two different organizations and have different implementations.
Unity.Mvc3 creates a child container per web request. This works well with the built-in HierarchicalLifetimeManager.
Unity.Mvc does not create a child container, but instead chose to create a new LifetimeManager called PerRequestLifetimeManager.

Unity PerRequestLifetimeManager re-using object in different requests

I've set up Unity for dependency injection for our project. The project itself is an ASP.NET application that uses both MVC and Web API.
For the database context, I'm using the PerRequestLifetimeManager. This is done so that the different bits of business logic are using the same context (and thus the same transaction).
In order to be able to use the PerRequestLifetimeManager, I've added references to the nuget packages Unity bootstrapper for ASP.NET MVC and Unity bootstrapper for ASP.NET Web API.
For use of this lifetime manager in Web API, the following line has been added to the startup code:
Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
The Unity container is set up for both MVC and Web API:
var container = BuildUnityContainer();
GlobalConfiguration.Configuration.DependencyResolver = new Microsoft.Practices.Unity.WebApi.UnityDependencyResolver(container);
System.Web.Mvc.DependencyResolver.SetResolver(new Microsoft.Practices.Unity.Mvc.UnityDependencyResolver(container));
In building the Unity container, the database context is set up to be resolved per request in the following way:
container.RegisterType<IDataContext>(new PerRequestLifetimeManager(),
new InjectionFactory(c =>
{
// Some code
return new DataContext(/* params */);
}
));
However, it seems that this code is not giving me a new DataContext for each request. It is giving me the same context in different places within a single request (which is fine). However, subsequent (web api) requests are being given the same instance of DataContext where I would expect a new one to be created for each new request. I also would expect the DataContext to be properly disposed of after the request is finished (the class implements IDisposable).
What's going on here? Am I missing a bit of configuration to make this work properly? Or isn't this supposed to work the way I expect it to?
The problem turned out to be that the UnityDependencyResolver was caching the resolved items over several requests. I had to change it to the UnityHierarchicalDependencyResolver and then it started resolving my items properly according to the associated LifetimeManager. The problem initially became more confusing when it appeared that even when using a TransientLifetimeManager, it would still return the same instance.
I found the answer in a different (yet somewhat related) question: using a Handler in Web API and having Unity resolve per request
So all I did was change
GlobalConfiguration.Configuration.DependencyResolver = new Microsoft.Practices.Unity.WebApi.UnityDependencyResolver(container);
to
GlobalConfiguration.Configuration.DependencyResolver = new Microsoft.Practices.Unity.WebApi.UnityHierarchicalDependencyResolver(container);
and all my problems were solved.

Dependency resolution as a separate project ..How to?

I am creating a new application using asp.net mvc, I'm using munq IOC container as my dependency injection..The issue is i want to create a new project for dependency resolution where i can register all the controllers of mvc project and the repositories of infrastructure project..I have to add Dependency Resolution project as a reference in my mvc app as thats the starting point... but the prob is in order to register the controllers in this separate app i need to have the reference of the mvc in the dependency Resolution project itself...but such a thing is not possible because that would cause a circular reference..
so how to resolve this issue? or what is the best way of managing the dependency resolution?
I don't want to end up registering everything in the Global.asax
Get the latest version from the source tab at Munq.Codeplex.com. This version has a view improvements and it is the version I am most familiar with, and I wrote it.
To prevent circular references for registration, create a class project that includes reverences to Munq.Interfaces and the interfaces and implementations you wish to register.
Create a class that implements IMunqConfig. It has one method void RegisterIn(IIocContainer container). Implement this method.
public class MyRegistration : IMuncConfig
{
public void RegisterIn(IIocContainer container)
{
container.Register<IMyInterface>(c => new MyImplementation());
// OR
container.Register<IMyInterface, MyImplementation>();
// Repeat as required for each thing to register
}
}
Then in global.asax
protected void Application_Start()
{
IocContainer = new Container();
Munq.COnfigurationLoader.FindAndRegisterDependencies(container);
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
This will search the bin directory for any dlls that have classes implementing IMunqConfig and execute the RegisterIn method on each. So just drop the registration dlls into the bin directory and registration happens automagically :)
Matthew
i want to create a new project for dependency resolution where i can
register all the controllers of mvc project and the repositories of
infrastructure project.
I wouldn't register MVC controllers in the same project as your repositories. The MVC app should "own" its composition, including registering its internal dependencies.
Registrations for your infrastructure project should ideally be in that project, especially if it's not something you're going to make available to other projects that use different DI containers. If that project needs to remain DI-agnostic then maybe it might make sense to separate DI registration into a separate project.
But I definitely wouldn't make a service (like your repository) responsible for registering the internal dependencies of its consumers (like your MVC app.)

Resources