I have a WEB API application and I am using UnityContainer as my DI.
Since I'm using UnitOfWork with Entity Framework I wanted to register the DataContext in the UnityContainer per each request.
I was disappointed to find that no LifeTimeManager exists that can give me a new scope per request. After digging a little more, I found that Unity.AspNet.Mvc does contain a PerRequestLifetimeManager. My questions are:
Is there a reason why Unity doesn't contain a PerRequestLifetimeManager? It seems to me that is a very common case to register something per request.
Is there a particular reason why Unity.AspNet.Mvc does contain PerRequestLifetimeManager?
Is there something I need to know if I am using Unity.AspNet.Mvc in a WebApi project?
In case of using Thread or Tasks, how does the container knows it belongs to the same request?
Is there a reason why Unity doesn't contain a PerRequestLifetimeManager? It seems to me that is a very common case
to register something per request.
The core library is for .Net projects. Only Asp.Net would have a Request.
Is there a particular reason why Unity.AspNet.Mvc does contain
PerRequestLifetimeManager?
Same as answer 1. Requests are an Asp.Net concept.
Is there something I need to know if I am using Unity.AspNet.Mvc in a
WebApi project?
Nope. You will most likely only be using the PerRequestLifetimeManager anyway. I would imagine the developers of Unity didn't see a need to publish a Mvc and a WebApi package when the two libraries would have been identical.
In case of using Thread or Tasks, how does the container knows it
belongs to the same request?
The container is just another object. The .Net framework manages objects from request to request and thread to thread. The container itself creates a unique scope at the beginning of a request and destroys it at the end of the request .Net does everything in between.
Related
In the last few days, we are recording different exceptions thrown by entity framework (version 6) on our live stage, which only occur occasionally and show error messages, which all relate to the database connection.
Not allowed to change the 'ConnectionString' property. The
connection's current state is closed.
The context cannot be used while the model is being created. This
exception may be thrown if the context is used inside the
OnModelCreating method or if the same context instance is accessed by
multiple threads concurrently. Note that instance members of DbContext
and related classes are not guaranteed to be thread safe.
Unexpected connection state. When using a wrapping provider ensure
that the StateChange event is implemented on the wrapped DbConnection.
The underlying provider failed on Open.
We can not remember that we've changed anything and as already said these errors occur only sometimes. We can not reproduce them on local stage.
Does anyone have an idea what is going wrong or how to investigate?
Edit: It is an ASP.NET MVC 5 application which uses Unity IoC for instantiation. We use a self-written PerRequestLifeTimeManager which runs absolutely smooth in other mvc applications.
Thanks to the hint of #Gerd Arnold and #Chris Pratt I was able to figure out the root-cause of my issue.
Indeed the exceptions where caused by an instance of DbContext which was used concurrently accross multiple requests. This DbContext is part of an service which is injected by Unity property injection into an action filter. What I didn't know yet is that action filters don't get instantiated per request in APS.NET MVC but they are cached and reused. So do not inject instances of DbContext or DbContext-based classes into action filters!
We solved that issue by calling DependencyResolver.Current.GetService<ClassType>() instead of using Dependency-attribute in our filter's code to get an instance of the respective dependency (Please note that you lose the testability of the filter through this workaround)
It took me many hours to find the solution. To those users who occasionally encounter the same errors as mentioned in my question I would recommend check your appliation for any DbContext-based classes which might get used concurrently accross requests/threads.
Check your Unity IoC rules
Look for classes which do not get instantiated through IoC but might be used concurrently.
Check all steps along the MVC request lifecycle
I am creating a WFC Restful service and there is a need to persist a variable that will be persist per user, is there a way I can achieve this without having to pass the variable to all my calls?
I am using trying to log the process of the user throughout the process, weather their request has failed or succeed, IP address, when they requested the action, failure time, etc.
Please note I am new to WCF, thanks in advance.
I recently worked on this (except it wasn't RESTFUL). You could transmit information through HTTP headers and extract that information on the service-side. See http://trycatch.me/adding-custom-message-headers-to-a-wcf-service-using-inspectors-behaviors/
For the client ID itself I can suggest two places to put it. One is OperationContext.Current.IncomingMessageProperties. Another is CorrelationManager.StartLogicalOperation which allows you to define a logical operation - that could be the service request, beginning to end - or multiple operations - and retrieve a unique ID for each operation.
I would lean toward the latter because it's part of System.Diagnostics and can prevent dependencies on System.ServiceModel. (The name CorrelationManager even describes what you're trying to do.)
In either case I would look at interception. That's the ideal way to read the value (wherever you store it) without having to pollute the individual methods with knowledge of logging and client IDs. (I saw from your message that you're trying to avoid that direct dependency on client IDs.)
Here's some documentation on adding Windsor to your WCF service. (At some point I'll add some end-to-end documentation on my blog.) Then, when you're using Windsor to instantiate your services, you can also use it to instantiate the dependencies and put interceptors around them that will perform your logging before or after those dependencies do their work. Within those interceptors you can access or modify that stack of logical operations.
I'm not doing Windsor justice by throwing out a few links. I'd like to flesh it out with some blog posts. But I recommend looking into it. It's beneficial for lots of reasons - interception just one. It helps with the way we compose services and dependencies.
Update - I added a blog post - how to add Windsor to a WCF service in five minutes.
I am having a Web API application in which the controller has Services/Repositories etc. injected into it through Dependency Injection (Unity). Let's assume that I have an IStuffService that needs the IPrincipal of the current request (or a wrapper around it).
The problem with Web API seems to be that the only reliable source of the current Request/User is the Request property on the instance of the ApiController. Anything static (be it HttpContext.Current, CallContext.Get/SetData or Thread.Get/SetData) is not guaranteed to be on the same thread due to the sync nature of Web API.
How do I reliably ensure that Request-specific context is passed through dependencies, and more importantly, that the operation retains the correct IPrincipal all the way through the operation?
Two options:
Every method that needs an IPrincipal has it as an argument to the method - that is the most reliable way, but it also requires me to have that thing in every method signature
Inject the IPrincipal into the ctor of the Service, spinning up a new insance of the object graph on every request, using a DependencyOverride in Unity: container.Resolve(opType, new DependencyOverride(typeof(IPrincipal), principal))
Option 2 means that my method signatures are clean, but it also means I need to make sure all dependencies are using the TransientLifetimeManager, not a Singleton or even Per-Thread one.
Is there a better solution than I'm not seeing?
From the comments:
#MichaelStum, I believe HttpContext.User should be flowed correctly
across async/await (within the same HTTP request). Is it not for you?
– Noseratio 17 hours ago
#Noseratio See the other answers - in .net 4.0, it's bound to the
current thread and was not properly maintained. It seems that in 4.5,
this might be fixed. That said, HttpContext.Current is still not that
appropriate in Web API because on self-hosted ones there is no
HttpContext.Current.
AFAIK, there's no proper support for async/await in ASP.NET 4.0 anyway (you probably can use Microsoft.Bcl.Async for the language support, but there is no ASP.NET runtime support, so you'd have to resort to AsyncManager to implement the TAP pattern).
That said, I'm 99% sure Thread.CurrentPrincipal would still be correctly flowed across await continuations in ASP.NET 4.0. That's because it gets flowed as a part of ExecutionContext flow, rather than by synchronization context. As to HtttContext.Current.User, I'm not sure if it would flow correctly in ASP.NET 4.0 (although it certainly does in ASP.NET 4.5).
I've re-read your question, but could find an explicit complaint about Thread.CurrentPrincipal not being correctly flowed. Are you experiencing this issue in existing code (if so, it probably would be a bug in ASP.NET)?
Here's a list of related questions, answered with some great insights by Stephen Cleary:
Understanding context in C# 5 async/await
Why is an "await Task.Yield()" required for Thread.CurrentPrincipal to flow correctly?
Using ASP.NET Web API, my ExecutionContext isn't flowing in async actions
This blog post by Scott Hanselman is also related, although he speaks about WebForms:
System.Threading.Thread.CurrentPrincipal vs. System.Web.HttpContext.Current.User or why FormsAuthentication can be subtle
If you're concerned about self-hosting scenarios, I believe Thread.CurrentPrincipal will still be flowed correctly there (once having been set to a correct identity). If you want to flow any other properties (besides those which get automatically flowed with ExecutionContext), you can roll out your own synchronization context. Another option (not so nice, IMO) is to use custom awaiters.
Finally, if you face a situation where you actually require thread affinity across await continuation (much like in a client side UI app), you have such option, too (again, using a custom synchronization context):
How to use non-thread-safe async/await APIs and patterns with ASP.NET Web API?
The ultimate answer is that our IoC containers need to be changed to support async/await better.
Background:
The behavior of async/await around this changed between .NET 4 and .NET 4.5. In .NET 4.5 the SynchronizationContext was introduced and it will correctly restore HttpContext.Current (see http://msdn.microsoft.com/en-us/magazine/gg598924.aspx). However, it is often a best practice to use .ConfigureAwait(false) (see "Configure Context" in http://msdn.microsoft.com/en-us/magazine/jj991977.aspx) and that specifically requests that the context not be preserved. In that case you would still have the issue you describe.
Answer:
The best answer I have been able to come up with in my own code is to be sure to request the dependency that comes from HttpContext.Current (in your case IPrincipal) early in the web request so that is is loaded into the container.
I don't have any experience with Unity, but in Ninject this would look something like:
kernal.Bind<IPrincipal>().ToMethod(c => HttpContext.Current.User).InRequestScope();
Then I would be sure to load the IPrincipal early in the web request before you have lost the context. Either in BeginRequest or as a dependency of the controller. That will cause the IPrincipal to be loaded into the container for this request.
Note: There are still situations where this may not work. I don't know if Unity has this issue, but I know Ninject does. It actually uses the HttpContext.Current, to determine what request is active. So if you try to resolve something from the container later, like a service locator or factory then it may not be able to resolve.
I know this is an old question I have worked with option one (in the question) and, it works.
UPDATE: I deleted my answer as I realized I've posted something that doesn't work.
Sorry for any inconvenience.
How do I reliably ensure that Request-specific context is passed
through dependencies, and more importantly, that the operation retains
the correct IPrincipal all the way through the operation?
I don't think you should do this. Your service is a lower layer than your Api controller. Your service should not depend on any classes related to the higher layer, otherwise your service could not be reused, for example: when you need to build a win forms application on top of the existing services.
IPrincipal is not appropriate to be injected into our services as it's web application related . When we pass this information down to lower layers (service), we should pass our neutral-classes or just a userId to decouple our services from the application using it.
You should define your own classes for Users and anything request-related to be used in our services layer as it's more domain-related. With this, your service-layer is application-layer (web, win forms, console,..) agnostic:
public class AppPrincipal : IAppPrincipal
{
public int UserId { get; set; }
public string Role { get; set; }
//other properties
public AppPrincipal() {
}
public AppPrincipal(int userId, string role):this() {
UserId = userId;
Role = role;
}
}
Then you can register IAppPrincipal as per-request scope in your web application and populate all the properties using your IPrincipal. The will initialize your IAppPrincipal for your entire object graph before any await/async calls. Example code with Unity:
public void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IAppPrincipal>(
new PerRequestLifetimeManager(),
new InjectionFactory(c => CreateAppPrincipal()));
}
public IAppPrincipal CreateAppPrincipal()
{
var principal = new AppPrincipal();
principal.UserId = //Retrieve userId from your IPrincipal (HttpContext.Current.User)
principal.Role = //Retrieve role from your IPrincipal (HttpContext.Current.User)
return principal;
}
The key here is that we already decouple our service layer from the web. If you need to reuse your service layer to build a windows form or console application, you could register IAppPrincipal as singleton and populate it differently.
We don't need to deal with platform-related problems like async/await
I have one project functioning perfectly using Unity. I try switching to use Simple Injector instead and now NO changes ever get saved in my database. I believe it has to do with the lifetime of the registered components. Here is the Unity container registration:
private IUnityContainer GetUnityContainer()
{
IUnityContainer container = new UnityContainer()
.RegisterType<IDatabaseFactory, DatabaseFactory>(
new HttpContextLifetimeManager<IDatabaseFactory>())
.RegisterType<IUnitOfWork, UnitOfWork>(
new HttpContextLifetimeManager<IUnitOfWork>())
.RegisterType<ICategoryRepository, CategoryRepository>(
new HttpContextLifetimeManager<ICategoryRepository>())
.RegisterType<ICategoryService, CategoryService>(
new HttpContextLifetimeManager<ICategoryService>());
return container;
}
And here is the new Simple Injector registration.
container.Register<IDatabaseFactory, DatabaseFactory>();
container.Register<IUnitOfWork, UnitOfWork>();
container.Register<ICategoryRepository, CategoryRepository>();
container.Register<ICategoryService, CategoryService>();
I'm not sure how the HttpContextLifetimeManager comes into play with Simple Injector. MVC is the client for the unity example, but I'm changing to a WPF project and Simple Injector. Any suggestions are much appreciated. Thanks.
#Steven. Thanks for your comment. I just discovered that since my RepositoryBase and my UnitOfWork inject an IDatabaseFactory in their constructors that I needed to use container.RegisterSingle<IDatabaseFactory, DatabaseFactory>(). This resolved one issue. I still have a problem with lifetime though. Since my consuming app is WPF, how will the RegisterPerWebRequest work?
My project has a DataLayer >> BusinessLayer >> WcfService >> WPF Front end. Simple Injector is set on the WcfService project and the business layer has Boostrapper to register items there. As of now, my WPF client will GetAllCountries() and display in a grid. If I change the name of one and try to update, I get the "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key." error. I've done some debugging and find that after the GetCountries service call in the WPF client, when I go back to try to update, I see ALL of the countries are attached to the context via dbContext.ChangeTracker.Entries(). At this point I should have NO entities being tracked as my context should have been disposed after the first unit of work.
In an MVC app the RegisterPerWebRequest fixes that, but what is the equivalent for WPF? I'm going to install the extension now and try it anyway but I have a feeling it isn't the solution I'm looking for.. or is it? Thanks again for the help.
OK. I did a bit more digging and found a solution that works. I'm just not sure if it's the correct one. Anyway, now in my BLL where there is a bootstrapper to register things, I can register like this:
container.RegisterPerWcfOperation<IDatabaseFactory, DatabaseFactory>();
container.RegisterPerWcfOperation<IUnitOfWork, UnitOfWork>();
container.RegisterPerWcfOperation<ICountryRepository, CountryRepository>();
That gives me what I was looking for. Only a single instance of DatabaseFactory is ever created and thus my repository and unit of work share it like they should. Also, after GetCountries() on the client, when I do my second call to the service to perform and update, I check the dbContext.ChangeTracker.Entries() and see that there are NO entities being tracked, which is correct. I can now attach, set to modify, and call SaveChanges without getting the duplicate key error. Does this seem ok? Thanks.
The Register overloads over Simple Injector register types using the transient lifestyle (which means no caching). Every time you request an instance (or inject an instance) a new instance is created. In Unity this is the same; the default lifestyle is transient.
It seems that registering those types with a Per Web Request lifestyle is quite essential. It's not strange that changes are not committed to the database when the class that does those commits on an IUnitOfWork gets a different instance than the class who actually makes the changes to the IUnitOfWork.
Simple Injector's equivalent to Unity's HttpContextLifetimeManager is the WebRequestLifestyle. This lifestyle is not part of the core library, but is available as NuGet package.
After you included this in your project, you can do the following registration:
container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
container.Register<IDatabaseFactory, DatabaseFactory>(Lifestyle.Scoped);
container.Register<IUnitOfWork, UnitOfWork>(Lifestyle.Scoped);
container.Register<ICategoryRepository, CategoryRepository>(Lifestyle.Scoped);
container.Register<ICategoryService, CategoryService>(Lifestyle.Scoped);
Or the equivalent:
Lifestyle lifestyle = new WebRequestLifestyle();
container.Register<IDatabaseFactory, DatabaseFactory>(lifestyle);
container.Register<IUnitOfWork, UnitOfWork>(lifestyle);
container.Register<ICategoryRepository, CategoryRepository>(lifestyle);
container.Register<ICategoryService, CategoryService>(lifestyle);
The default behavior of the WebRequestLifestyle is to dispose created instances when the web request ends. No special registration for this is required (Simple Injector hooks up an HttpModule for you when the application starts).
UPDATE:
My apologies for not reading your question to the last line. I missed the fact that you want to configure it using a WPF client.
As you probably know, since your client is a different application than the WCF service is, you'll have two Composition Roots in your system; one for the client, one for the service. Their registration will probably be quite different. Starting with Simple Injector v4.1, for a WCF service, you would indeed need a AsyncScopedLifestyle or when you follow the reference architecture at dotnetjunkie/solidservices, you'll find it as easy to use ThreadScopedLifestyle and define a scope explicitly in your two Execute methods.
I find managing the lifetime of objects in clients of two tier applications (client -> database) rather hard, since it is hard to define a unit of work for a certain scope. Since you are using the command/handler + query/handler approach, things will get so much easier. There won't be any unit of work on the client. Just on the server. Your presenter can just depend on several IQueryHandler<TQuery, TResult> and ICommandHandler<TCommand> interfaces and you're done. A query doesn't change state and a command should be an atomic operation. In other words, a unit of work is only needed within the boundary of an executing command.
I have troubles consuming unity container in ASP.NET MVC3 application.
I have several project with interfaces and their implementation. All interface to concreete type binding is performed in the application startup method.
I have several problems with this aproach:
1) How to handle registration of types that are not dirrectly required by MVC application but by classes that it using (Repository uses ContextManager to retrieve context instance). If this class is located in assembly that is not used by mvc app, I will have to add reference to it.
2) How to share configured container? Should I create separate assembly with static class wich will store created by mvc app container?
3) What kind of unity container usage can possibly bring cross thread problems? How to register singletons so that they will be avaliable only in this thread (web server call) etc.
You should explicitly reference all assemblies to your ASP.NET MVC application. It is the outermost layer in the onion architecture and it is allowed to know about inner layers. All assemblies must be in the bin folder anyways so the ASP.NET MVC application will know about them one way or another. Just externalize your DI framework configuration into a single place in your ASP.NET MVC application.
See 1.
Per thread storage could be dangerous in ASP.NET. Per HTTP Context is better.