All,
There has been a lot of posts about Unity Lifetime Managers but I have yet to find someone state a good rule of thumb for "in these cases you should always use X". Let me describe my application, I have an ASP.NET MVC 4 Web Application. I have a Visual Studio solution containing 3 projects, my 'Core' project which has all of my EF stuff, a testing project, and the MVC Web Project. I am using Unity for dependency injection and have the following code right now:
// Context
container.RegisterType<IDatabaseFactory, DatabaseFactory>(
new ContainerControlledLifetimeManager();
container.RegisterType<UnitOfWork>(
new ContainerControlledLifetimeManager());
However, I'm noticing that my context is not recreated with every new web request which is what I think I would want (let me know if I'm wrong in that assumption). I'm having a hard time analyzing all of the information from the sites listed below and have read about a lot of people creating their own class named PerHttpRequestLifetimeManager to handle this.
What truly is the best practice here?
Understanding Lifetime Managers by Microsoft's Developer Network - http://msdn.microsoft.com/en-us/library/ff660872(v=PandP.20).aspx
MVC DI & Unity with Lifetime Manager via CodeProject - http://www.codeproject.com/Articles/424743/MVC-DI-Unity-with-Lifetime-Manager
ASP.NET MVC Tip: Dependency Injection with Unity Application Block via Shiju Varghese's Blog - http://weblogs.asp.net/shijuvarghese/archive/2008/10/24/asp-net-mvc-tip-dependency-injection-with-unity-application-block.aspx
MVC, EF - DataContext singleton instance Per-Web-Request in Unity via Stack Overflow - MVC, EF - DataContext singleton instance Per-Web-Request in Unity
Inject same DataContext instance across several types with Unity via Stack Overflow - Inject same DataContext instance across several types with Unity
Yes, you usually want one DbContext per request.
A PerHttpRequestLifetimeManager or child container created on every request are the typical ways this is handled.
The latest release of Unity introduces the Unity bootstrapper for ASP.NET MVC which has a new built-in lifetime manager: PerRequestLifetimeManager.
You can read more in the Developer's Guide to Dependency Injection Using Unity chapter 3, Dependency Injection with Unity.
Related
This question already has answers here:
Ioc/DI - Why do I have to reference all layers/assemblies in application's entry point?
(4 answers)
Closed 9 years ago.
I have a Visual Studio solution that has the following:
MyProject.Domain - POCOs.
MyProject.Data - ORM (Entity Framework DbContext).
MyProject.Services - Wrapper around the DbContext. Contains classes that perform business logic.
MyProject.Web - MVC app that uses the service layer.
For my MVC app, I am using Ninject to inject services into my MVC controllers. The binding in my MVC project looks like this:
kernel.Bind<ISomeService>().To<SomeService>();
This part is working fine. However, I would further like to inject an IDbContext into my services, and the examples I see online are a little confusing. The examples I see online look make the above code look like this:
kernel.Bind<ISomeService>().To<SomeService>();
kernel.Bind<ISomeDbContext>().To<SomeDbContext>();
Now, since SomeDbContext is located in MyProject.Data, this means that I have to add a reference to the ORM project in my MVC project. This works, but this seems to defeat the purpose of IoC. The MVC project shouldn't "know" about the ORM, right? Why isn't this considered poor design? What is the proper way to manage this dependency?
If you configure all your dependencies in the MVC project, it is needed to have reference to project that holds implementations.
I am OK with this solution and if it is really needed to avoid this kind of reference you can try the following approach.
I am not familiar with Ninject, but in CastleWindsor it is possible to write installers anywhere (within any assembly) and then invoke them during type registration process from your MVC project. There is a SO question that might help you: Convert this Castle Windsor Installer to Ninject to register all repositories.
There won't be dirrect reference to ORM project from MVC project if you add a project with "installers" that knows about ORM project and its interfeces. In this case your MVC project should know about DataAccess layer interfaces and the project with installers only.
I am looking for some best practice advice with regards to building a self contained service, that is a DLL with all of the domain logic and data layer. I would like to use an off the self CMS, such as orchard, then talk to the service to carry out CRUD operations. The service should have it's own IOC, and ORM, in this case I am using Ninject and Entity Framework. In this design I will have a separate database than the CMS, and can port it to other CMS systems when required.
The CMS should start the service and pass it a connection string or file name. If I use orchard it has different ORM, and IOC frameworks, so this leads me to wanting to keep Ninject and Entity Framework inside the service.
I have setup an experiment where the DbConext and domain are in the service DLL, and I call it from a console app. This only works if I have entity framework referenced in the console application, even though I don't use it in that dll. Here is the error message when EF is not referenced by the console app.
No Entity Framework provider found for 'System.Data.SqlClient' ADO.NET provider.
Why is this and how best to solve my design problem?
If your library (DLL) depends on Entity Framework, it's perfectly normal that you need to reference both in your application (whether it's console, web or whatever else). You always need to reference all dependencies.
Wiring your custom library with Orchard would be fairy simple. The only thing you'd need to do on Orchard side would be to register the services coming from your library with Autofac, in order to have them available for dependency injection. This post describes a similar scenario to yours.
Please bear in mind that using multiple database connections is a bit troublesome in Orchard <= 1.6, because of the usage of TransactionScope - you need to run all your custom database code in a suppressed scope, otherwise you'd have transaction errors and/or MSDTC-related problems. It will be a non-issue since Orchard 1.7 which is going to arrive in about a week. I'd strongly recommend waiting for the new version. You can also fetch the pre-release code from 1.x branch.
I am new in MEF. I am working on a C# WPF application and using Prism with MEF.
Please tell me how can I create single instance per thread of a class using MEF.
Thanka a lot
DJ
In the current version of MEF, you would need to develop a complex hierarchy of containers in order to accomodate this requirement (singleton per thread). Since you are new to MEF, this would be quite tricky to implement. Here is a link with more information about this:
http://codebetter.com/glennblock/2009/08/16/should-i-use-mef-for-my-general-ioc-needs/
I believe one of the new options in the new version of MEF (currently called MEF2) will be better options for how to handle object instantiation. You can read more about it at the BCL blog or here:
http://mef.codeplex.com/
I'm trying to design the architecture for a new LOB MVVM project utilising Caliburn Micro and nHibernate and am now at the point of looking into DI and IOC.
A lot of the examples for bootstrapping Caliburn Micro use MEF as the DI\IOC mechanism.
What I'm struggling with is that MEF seems to by reasonably popular but the idea of the Mef [Imports] annotations smells to me like another flavour of a Service Locator?
Am I missing something about MEF whereby almost all the examples I've seen are not using it correctly or have I completely not understood something about how it's used whereby it side steps the whole service locator issues?
MEF is not a Service Locator, on it's own. It can be used to implement a Service Locator (CompositionInitializer in the Silverlight version is effectively a Service Locator built into MEF), but it can also do dependency injection directly.
While the attributes may "smell" to you, they alone don't cause this to be a service locator, as you can use [ImportingConstructor] to inject data at creation time.
Note that the attributes are actually not the only way to use MEF - it can also work via direct registration or convention based registration instead (which is supported in the CodePlex drops and .NET 4.5).
I suppose if you were to just new up parts that had property imports and try to use them, then you could run into some of the same problems described here: Service Locator is an Anti-Pattern
But in practice you get your parts from the container, and if you use [Import] without the additional allowDefault property, then the part is required and the container will blow up on you if you ask for the part doing the import. It will blow up at runtime, yes, but unlike a run of the mill service-locator, its fairly straightforward to do static analysis of your MEF container using a test framework. I've written about it a couple times here and here.
It hasn't been a problem for me in practice, for a couple of reasons:
I get my parts from the container.
I use composition tests.
I'm writing applications, not framework code.
I have a ASP.Net MVC 3 photo gallery, which is designed in this way:
Data Repositories(IImageRepoSitory, ITagRepository etc)
|
Services (IGalleryService, IWebService etc)
|
Web Application
Which I use Ninject to inject the required Services and repositories into the web application.
Before I use actual database, I used a simple ArrayList (and JSON serialization) as my presistent logic (That will be JsonImageRepository/JSonTagRepository) which works perfectly fine. But later on, I moved to EF4 CTP5 (Code First), and many problems appeared. Basically, I injected those repositories and services as Singleton (which declared in Global.asax.cs), but when I have several threads that access the repositories, it saids:
Data Connection is closed.
I changed to something like Thread Mode or Request Mode in Ninject but various exception raised (regarding to multiple instances of context, so I think Singleton should be the only option).
Is there anything wrong with the design? or how should I configure those components?
Normally, repository access should be in request scope (at least the ones that change data). I recommend looking at bob's blog posts about a repository pattern implementation using Ninject and NHibernate. It should be pretty much the same for EF4:
http://blog.bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/
http://blog.bobcravens.com/2010/07/using-nhibernate-in-asp-net-mvc/
http://blog.bobcravens.com/2010/09/the-repository-pattern-part-2/
I planned adding this to the sample application in near future.