ServiceStack self-hosted application with per-request lifetime scope - c#

Working with ServiceStack I've stuck with the problem of objects lifetime management in self-hosted web application.
My requirements:
Need of per-request objects lifetime scope.
I'm using Castle Windsor IoC with implemented ServiceStack IoC adapter.
My application is self-hosted with base class AppHostHttpListenerPoolBase (ServiceStack v4)
Probably one day I want to move on IIS, thus it's must be flexible.
General problem:
Castle Windsor IoC implements its own per-request lifetime strategy but it is binded to http modules, thus it works only with IIS hosted apps. Hence, I have to implement my custom IScopeAccessor (provided by Castle Windsor) to handle objects lifetime. The problem here is in absence of hooks which I can use to bind to current request.
Given
public class MyScopeAccessor : IScopeAccessor
{
public ILifetimeScope GetScope(CreationContext context)
{
//implement it
}
}
I have to implement GetScope method.
There are two main ideas I cannot complete:
Using of [Threadstatic]
In MyScopeAccessor I just store
[ThreadStatic]
private static ILifetimeScope _currentLifetimeScope;
and create new scope after first GetScope if it's not initialzied yet.
Problems:
Hard to dispose. Best way to dispose _currentLifetimeScope is to implement custom IServiceRunner (or inherit from ServiceRunner) overriding AfterEachRequest method. But I don't exactly know if AfterEachRequest is actually executed in request thread.
Moving to IIS can cause some problems because as I know IIS doesn't guarantee unchangeable binding between theads and request contexts.
Using of IRequest instance
In MyScopeAccessor I just store
private static readonly ConcurrentDictionary<IRequest, ILifetimeScope> LifetimeScopes;
and create and dispose current lifetime scope in corresponding custom ServiceRunner methods (OnBeforeEachRequest, OnAfterEachRequest).
Problems:
I don't know how to get access to current request globally from GetScope, MyScopeAccessor knows nothing about services and requests.
Also, it is interesting if ServiceStack default Funq IoC solves this problem.

Funq does handle RequestScoped dependencies which stores Request Context dependencies in the RequestContext.Instance.Items[] dictionary.
Any disposables can be registered in RequestContext.Instance.TrackDisposable() are automatically disposed of at the end of the request.
At the end of each request AppHost.OnEndRequest() is fired which goes through and releases any dependencies stored in the RequestContext for that request.
If your Windsor ContainerAdapter implements the IRelease interface it's automatically called to release any instances which can be handled itself. Both these API's are overridable in your AppHost if you want to change the default behavior:
public virtual void OnEndRequest()
{
var disposables = RequestContext.Instance.Items.Values;
foreach (var item in disposables)
{
Release(item);
}
RequestContext.Instance.EndRequest();
}
public virtual void Release(object instance)
{
try
{
var iocAdapterReleases = Container.Adapter as IRelease;
if (iocAdapterReleases != null)
{
iocAdapterReleases.Release(instance);
}
else
{
var disposable = instance as IDisposable;
if (disposable != null)
disposable.Dispose();
}
}
catch { /*ignore*/ }
}

Related

How to correctly and safely dispose of singletons instances registered in the container when an ASP.NET Core app shuts down

I am looking for guidance on how to correctly and safely dispose of registered singleton instances when my ASP.NET Core 2.0 app is shutting down.
According to the following document, if I register a singleton instance (via IServiceCollection) the container will never attempt to create an instance (nor will it dispose of the instance), thus I am left to dispose of these instances myself when the app shuts down.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.0 (2.1 has the same guidance)
I enclose some pseudo code that illustrates what I am trying to achieve.
Note I am having to maintain a reference to IServiceCollection since the IServiceProvider provided to the OnShutDown method is a simple service locator and doesn't give me the ability to execute complex queries.
When the app shuts down I want a generic way to ensure all singleton instances are disposed. I could maintain a reference to all these singleton instances directly but this doesn't scale well.
I originally used the factory method which would ensure the DI managed the lifetime of my objects, however, the execution of the factory method happened at runtime in the pipeline of handling a request, which meant that if it threw an exception the response was 500 InternalServerError and an error was logged. By creating the object directly I am striving for faster feedback so that errors on startup lead to a automatic rollback during the deployment. This doesn't seem unreasonable to me, but then at the same time I don't to misuse the DI.
Does anyone have any suggestions how I can achieve this more elegantly?
namespace MyApp
{
public class Program
{
private static readonly CancellationTokenSource cts = new CancellationTokenSource();
protected Program()
{
}
public static int Main(string[] args)
{
Console.CancelKeyPress += OnExit;
return RunHost(configuration).GetAwaiter().GetResult();
}
protected static void OnExit(object sender, ConsoleCancelEventArgs args)
{
cts.Cancel();
}
static async Task<int> RunHost()
{
await new WebHostBuilder()
.UseStartup<Startup>()
.Build()
.RunAsync(cts.Token);
}
}
public class Startup
{
public Startup()
{
}
public void ConfigureServices(IServiceCollection services)
{
// This has been massively simplified, the actual objects I construct on the commercial app I work on are
// lot more complicated to construct and span several lines of code.
services.AddSingleton<IDisposableSingletonInstance>(new DisposableSingletonInstance());
// See the OnShutdown method below
this.serviceCollection = services;
}
public void Configure(IApplicationBuilder app)
{
var applicationLifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
applicationLifetime.ApplicationStopping.Register(this.OnShutdown, app.ApplicationServices);
app.UseAuthentication();
app.UseMvc();
}
private void OnShutdown(object state)
{
var serviceProvider = (IServiceProvider)state;
var disposables = this.serviceCollection
.Where(s => s.Lifetime == ServiceLifetime.Singleton &&
s.ImplementationInstance != null &&
s.ServiceType.GetInterfaces().Contains(typeof(IDisposable)))
.Select(s => s.ImplementationInstance as IDisposable).ToList();
foreach (var disposable in disposables)
{
disposable?.Dispose();
}
}
}
}
It's the DI's job to dispose of any IDisposable objects it creates, whether transient, scoped or singleton. Don't register existing singletons unless you intend to clean them up afterwards.
In the question's code there's no reason to register an instance of DisposableSingletonInstance. It should be registered with :
services.AddSingleton<IDisposableSingletonInstance,DisposableSingletonInstance>();
When the IServiceCollection gets disposed, it will call Dispose() on all the disposable entities created by it. For web applications, that happens when RunAsync() ends;
The same holds for scoped services. In this case though, the instances will be disposed when the scope exits, eg when a request ends.
ASP.NET creates a scope for each request. If you want your service to be disposed when that request ends, you should register it with :
services.AddScoped<IDisposableSingletonInstance,DisposableSingletonInstance>();
Validation
For the latest edit :
By creating the object directly I am striving for faster feedback so that errors on startup lead to a automatic rollback during the deployment.
That's a different problem. Deployment errors are often caused by bad configuration values, unresponsive databases etc.
Validating Services
A very quick & dirty way to check would be to instantiate the singleton once all startup steps are complete with :
services.GetRequiredService<IDisposableSingletonInstance>();
Validating Configuration
Validating the configuration is more involved but not that tricky. One could use Data Annotation attributes on the configuration classes for simple rules and use the Validator class to validate them.
Another option is to create an IValidateable interface with a Validate method that has to be implemented by each configuration class. This makes discovery easy using reflection.
This article shows how the IValidator interface can be used in conjunction with an IStartupFilter to validate all configuration objects when an application starts for the first time
From the article :
public class SettingValidationStartupFilter : IStartupFilter
{
readonly IEnumerable<IValidatable> _validatableObjects;
public SettingValidationStartupFilter(IEnumerable<IValidatable> validatableObjects)
{
_validatableObjects = validatableObjects;
}
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
foreach (var validatableObject in _validatableObjects)
{
validatableObject.Validate();
}
//don't alter the configuration
return next;
}
}
The constructor gets all instances that implement IValidatable from the DI provider and calls Validate() on them
That's not accurate. Singletons are disposed at app shutdown, though it's kind of not actually all that relevant because when the process stops, everything goes with it anyways.
The general rule of thumb is that when using DI, you should use DI all the way down, which then means you'll almost never be disposing on your own, anywhere. It's all about ownership. When you new stuff up yourself, you're also then responsible for disposing of it. However, when using DI, the container is what's newing things up, and therefore, the container and only the container should then dispose of those things.
Thanks for the responses Panagiotis Kanavos and Chris Pratt and for helping to clarify how best to deal with this scenario. The two take away points are this:
Always strive to let the container manage the life cycle of your objects so when the app is shutdown the container will automatically dispose of all objects.
Validate all your configuration on app startup before it is consumed by objects registered in the container. This allows your app to fail fast and protects your DI from throwing exceptions when creating new objects.

How to configure simple injector container and lifestylse in a MVC web app with WebAPI, WCF, SignalR and Background Task

The simple injector documentation provides great examples on how to setup the container for WebRequest, Web API, WCF, ... but the examples are specific to one technology/lifestyle at a time. Our web application uses most of them together!
It is not clear to me how to configure the container to work with several lifestyles.
Let's say I have a MVC project with Web API. I have the following objects:
MyDbContext : My entity code first db context
IMyDataProvider implemented by MyDataProvider : Contains query logic and uses MyDbContext
MyController : MVC controller that uses IMyDataProvider
MyApiController : WebApi controller that uses IMyDataProvider
Should I create and configure one container for each type of lifestyle ?
When I register everything with RegisterPerWebRequest<T> is works in both types of controllers. Is this safe ? Or will I run into trouble when using async/await in a Web API controller?
What is the best configuration when I have both MVC and Web API controllers who get injected the same instances ?
Should I use a hybrid lifestyle ?
Now to complicate things... our application also uses background tasks and SignalR.
Both of these will sometimes occur outside of a WebRequest and need access to the same objects as described above.
The best solution would be to use a Lifetime scope ?
Would I need to create a new container for that lifestyle? or can I reuse/reconfigure my MVC/Web API container ?
Is there a triple lifestyle?
I have to say, I stumble on a similar scenario some time ago, I ended up by sharing my configuration over my web API and signalR, but you need to implement a custom lifestyle for signalR since it's not based on web request.
specially in signalR you'll find some issues handling per-web-request dependencies in a Hub some of them are going to be null like httpContext.Current among others.
The solution:
You need a hybrid lifestyle between WebRequestLifestlye and either Lifestyle.Transient, Lifestyle.Singleton, or LifetimeScopeLifestyle. I ended up I finished using the decorator pattern, you may read this post and this other post.
my decorator
public class CommandLifetimeScopeDecorator<T> : ICommandHandler<T>
{
private readonly Func<ICommandHandler<T>> _handlerFactory;
private readonly Container _container;
public CommandLifetimeScopeDecorator(
Func<ICommandHandler<T>> handlerFactory, Container container)
{
_handlerFactory = handlerFactory;
_container = container;
}
public void Handle(T command)
{
using (_container.BeginLifetimeScope())
{
var handler = _handlerFactory(); // resolve scoped dependencies
handler.Handle(command);
}
}
}
public interface ICommandHandler<in T>
{
void Handle(T command);
}
I managed the dependencies using a hub activator for signalR
public class MyHubActivator : IHubActivator
{
private readonly Container _container;
public MyHubActivator(Container container)
{
_container = container;
}
public IHub Create(HubDescriptor descriptor)
{
return _container.GetInstance(descriptor.HubType) as IHub;
}
}
a composite root file which is where you are going to handle your dependencies
public CompositRoot(Container container)
{
_container = container;
}
public container Configure()
{
// _container.Registerall container dependencies
return _container;
}
then share your composite root configuration when you are bootstrapping your app
var compositRoot = new CompositRoot(simpleInjector.Container); //simple injector instance
compositRoot.Configure();
For signalR
GlobalHost.DependencyResolver.Register(typeof(IHubActivator), () => new MyHubActivator(compositRoot));
and you may reuse your configuration among other projects!
my two cents
hope that helps!
Usually you don't need to have one container per lifestyle; In general you want to have one container instance per AppDomain. However, mixing Web API in the same project with MVC is from an architectural point of view a horrible idea IMO (as explained here, here, and here). So in case you are separating those parts into their own architectural blocks, you will already have less problems already.
But in case you are running MVC and Web API in the same project, this basically means that you will always be using Web API. The WebApiRequestLifestyle was explicitly built to work:
well both inside and outside of IIS. i.e. It can function in a
self-hosted Web API project where there is no HttpContext.Current.
(source)
In general, it is safe to use the WebRequestLifestyle in case you are only running in IIS when you have no intention to spin of parallel operations using ConfigureAwait(false) (which should be really rare IMO) as explained here.
So in the case you are still mixing Web API with MVC in the same project, there's no reason to use a hybrid lifestyle; you can simply use the same lifestyle. For doing background processing you might however need to build a hybrid lifestyle, but it every scenario needs a different hybrid. However, hybrids can be stacked up and you can easily create a 'triple lifestyle' if needed.
Since you want to do background processing with SignalR, you need to decide in what type of scoped lifestyle to run those background operations. The most obvious lifestyle is the LifetimeScopeLifestyle and this means you should make your scoped registrations using the following scoped lifestyle:
var hybridLifestyle = Lifestyle.CreateHybrid(
lifestyleSelector: () => HttpContext.Current != null,
trueLifestyle: new WebRequestLifestyle(),
falseLifestyle: new LifetimeScopeLifestyle());
A lifetime scope however needs to be started explicitly (as were the web request scope gets started implicitly for you if you include the SimpleInjector.Integration.Web.dll in your web application). How to do this depends on your design, but this q/a about SignalR might point you in the right direction.

Should creating a Unity Container be considered an expensive operation as it relates to resources and time?

I've recently started using Unity for dependency injections in .net.
I was under the impression that a Unity Container would most likely be a singleton or static member of a class. I saw another developer using it in a request handler that will receive a lot of traffic.
Is there some magic happening that keeps the cost low for creating a new Unity Container every time, or should this code be re-factored to only create the Unity container once?
This code is part of the implementing class of a .svc Service.
public string DoSomeWork(Request request)
{
var container = new UnityContainer().LoadConfiguration("MyContainer");
var handler = container.Resolve<RequestHandler>();
return handler.Handle(request);
}
Not 100% sure with Unity, but with most IoC containers, the creation of the container and especially the loading of container configuration is a reasonably expensive operation.
I have to question why this developer is utilizing the container in this manner however. Ideally the IoC container shouldn't even be a static or singleton object - it should be instantiated only to resolve the top level object of your dependency tree, and the rest of the objects in your application should be constructed automatically through dependency injection. In the case of your example, the class containing that method ideally would have the RequestHandler (ideally an interface of this) injected into it through the constructor so that class does not need to know about the IoC container.
This is not the right way to use an IOC container - basically your are using it as a service locator, but this will cause dependencies to the IOC container to be sprinkled all over the code base.
What you should do is have one central spot in your codebase where all dependencies are resolved and then use dependency injection (DI) to propagate the resolved concrete classes down the chain, i.e via constructor injection. So your class really should look something like this:
public class Foo
{
private readonly IRequestHandler _handler;
public Foo(IRequestHandler handler)
{
_handler = handler;
}
public string DoSomeWork(Request request)
{
return _handler.Handle(request);
}
}

Structuremap PerRequest lifecycle

I want to inject an instance into structuremap on the fly (i.e. outside of a registry/configuration) that lives for the life of the request.
Currently I'm doing this in the HandleBeginRequest event of an IHttpModule:
container.Configure(x => x.For<IMyClass>()
.LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest))
.Use(new MyClass()));
However, if at some point in the application's life I do:
ObjectFactory.WhatDoIHave();
I see as many configured instances for IMyClass as there have been requests (or at least a significant amount).
Thinking about it, this sort of makes sense given the code I have.
Is there a better way to inject an instance into the container just for the life of the current request in a way that doesn't pollute the whole container?
Thanks
Your problem is that you're registering the type in the container once per request, which is building up on the registrations. Configuring the container should ideally be made once in the application's lifecycle - typically in the Application_Start event for web applications.
Structuremap allows you to specify a creational function that is invoked upon creating the object, which will let you configure advanced object creation steps.
Instead of your current call to Configure in the Begin_Request event, stick the following in the container configuration during Application_Start.
For<IMyClass>().HttpContextScoped().Use(() => new MyClass());
Notice the lambda in the Use method. The lambda can contain any logic needed in order to create the object and it will be invoked one per lifecycle (per request in the case of HttpContext lifecycle).
I went with this in the end
For<IRequestContextStorage>()
.HybridHttpOrThreadLocalScoped()
.Use<RequestContextStorage>();
For<MyClass>()
.Use(c => c.GetInstance<IRequestContextStorage>().Get<MyClass>());
...
public class RequestContextStorage : IRequestContextStorage
{
readonly IDictionary<Type, object> hash;
public RequestContextStorage()
{
this.hash = new Dictionary<Type, object>();
}
public T Get<T>() where T : class
{
if(this.hash.ContainsKey(typeof(T)))
return this.hash[typeof (T)] as T;
return null;
}
public void Set<T>(T instance)
{
this.hash[typeof (T)] = instance;
}
}
...
static void HandleBeginRequest(object sender, EventArgs e) {
ObjectFactory.Get<IRequestContextStore>().Set(new MyClass());
}
If you only have one container, and you have multiple requests, you will run into this problem. I would suggest managing the per request instances yourself by storing them in HttpContext.Items.
If you want to be able to access it through the container, create a gateway class that holds no state and pulls your per request dependency out of HttpContext for you. Register that in your container, and update dependencies on the per request object to you the gateway.
Update
I can't believe I overlooked this before, what you really want is to use HttpContextLifecycle, which will cache a given instance in the HttpContext.Items collection, where it will be available throughout your request. You will still have multiple instances active during concurrent requests, but StructureMap can figure out which one to return based on HttpContext.Current.

Issues with Entity Framework Self Tracking Entities and ASP MVC .NET and Managed Extensibility Framework

BIG EDIT: This problem is probably being caused by MEF!
I'm using a service oriented architecture and have all my MVC controllers perform actions through the services.
I have a base service that looks like this:
public abstract class BaseService
{
protected MyObjectModel context;
public BaseService()
{
context = new MyObjectModel();
}
}
I then have services that inherit
[Export(typeof(IEmployeeService))]
public class EmployeeService : BaseService, IEmployeeService
{
public void NewEmployee(Employee newEmployee)
{
context.Employees.AddObject(newEmployee);
context.SaveChanges();
}
}
I have my controllers also inheriting from a base class that provides access to all the required services so they can just call:
EmployeeService.AddEmployee(new Employee() { Name = "JohnDoe"});
This all worked wonderfully until I started seeing that the ObjectContext wasn't accurately reflecting the database upon construction.
I put a breakpoint in the BaseService constructor and using Sql Server's Profiler saw that the brand new MyObjectModel wasn't even hitting the DB but pulling the data out of some cache presumably?
I stumbled upon the MergeOption property of the collections in the context and changing that made sure the data was fresh, but now I need to use that everytime I create a new service method that returns entities!
EDIT:
I've been stumbling along until I realised that my issues were probably being caused by MEF.
I have overridden the default ControllerFactory and implemented one that uses MEF to instantiate the services. What I'm probably seeing is MEF keeping the objects alive between calls.
So
1) Where can I read more on this behaviour? And what can I do to stop it and force a fresh composition every time the object is called?
Thanks.
I solved this issue eventually after hours of pulling out my hair.
My implementation of ControllerFactory looked like this.
public class ControllerFactory : IControllerFactory
{
CompositionContainer container;
DefaultControllerFactory controllerFactory;
public ControllerFactory()
{
container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
controllerFactory = new DefaultControllerFactory();
}
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
var controller = controllerFactory.CreateController(requestContext, ControllerName);
container.ComposeParts(controller);
return controller;
}
public void ReleaseController(IController controller)
{
var disposable = controller as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
}
And I called this line in my Application Startup.
ControllerBuilder.Current.SetControllerFactory(new ControllerFactory());
What was happening was that the controller factory was only being initialised once per AppDomain cycle and therefore my composition container was as well. My service classes weren't marked specifically for Shared or Non Shared usage, so the container held onto a reference of each one. Every time the ControllerFactory created a new controller on each call it would populate the service properties with the references it still held from the last call, including the old ObjectContext which was resulting in the mismatch in data.
My entire problem was solved by adding
[PartCreationPolicy(CreationPolicy.NonShared)]
to each service enforcing a fresh version each time.
Now I'm left to wonder if MEF is STILL holding onto thos references, because that ObjectContext is not a small thing to hold onto. Is this a memory leak waiting to happen?

Categories

Resources