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.)
Related
I have a little bit of a "strange practise" question. The requirement on an architecture of our project is to setup Web API with (if possible) all MVC goodness within WCF project. That means that WCF and Web API web services would be stood up along each other within one project.
Is this even doable? I've given it a short go and found that even merging the web configs of two projects is very hard.
Thank you for your suggestions and comments,
Jakub
I followed these steps and it worked fine:
Make sure your WCF service is working correctly.
Install WebAPI to your project through Nuget Package Manager
Install-Package Microsoft.AspNet.WebApi
Create Controller folder and write your controller class and methods.
Create global.asax file
Register routes for your services in Application_Start method.
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
private void RegisterRoutes(RouteCollection routes)
{
routes.MapHttpRoute(
"webapi_route",
"/{controller}/{action}/{id}",
new { controller = "controller_name", action = "method_name", id = RouteParameter.Optional }
);
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(service_name)));
}
In fact there are no major restrictions on the use of the two technologies within the same project. By default wcf has a different "pipe line" than asp.net, but until this can be changed. Using the configuration below in web.config it is possible to configure wcf to use the same asp.net pipe line thus sharing the whole life cycle of the objects of the request. But do not believe that this approach is usual for all cases, other factors need to be considered to make that decision, for example, how do you plan to distribute your application? When you release a version of wcf you will also be releasing the web.api, in many cases you may not want this result.
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
It is possible but with losing the MVC goodness (that means that you will not be able to use for example the built in automatic online documentation for your web services).
Just install Web API through NuGet and then register your route in global.asax. Create your api controller and it should be all good.
EDIT 01.02.2017:
This is no longer true. Since Microsoft approach was to merge MVC and Web API controller. Now anything is possible.
I have a piece of code that encapsulates functionality that isn't specific to Orchard. However i need to make it available in Orchard via dependency injection. So, I built up an Autofac Module that registers all components (types), but I can't find a way to inform Orchard's Autofac Container about it.
From what i red, there are two ways to add a module to a container:
By supplying the module at to the ContainerBuilder (usually at start-up),
Or by updating the already built Container at runtime with a ContainerBuilder
I can approach the problem in the first way, but I rather do a variant of the second if there is such?
Just add a class deriving from Autofac.Module to your Orchard module and that's it. It will get automatically picked by Orchard during the container construction.
Piotr Szmyd's answer is fundamentally correct, but here's some more detail:
Your Orchard Module is the new .csproj that you've added to the Orchard.sln
Add Autofac as a reference to that csproj (make sure you use the version included with Orchard - not nuget. See here for more details about that problem)
Then add a class that derives from Autofac.Module and which implements Load(ContainerBuilder).
e.g.
using System;
using Autofac;
namespace MyCustom.Module.Namespace
{
public class LoaderModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<MyClass>().As<IMyInterface>();
}
}
}
As an additional note:
The Autofac registration code only gets invoked at application startup time.
If you are running with the site sitting locally in IIS and the code in VS, then the dynamic compilation nature of Orcahrd means that when you recompile the code, the application doesn't stop.
So in order for this Autofac registration code to be hit (and also for any channges to it to take effect) you have to iisreset to kill the application, so that it reloads the Autofac Registrations.
I am working on an ASP .NET Mvc 3 App and have installed Ninject.Mvc3 using Nuget. I now have the App_Start folder and then ninject class. I have seen plenty of examples on how to configure NHibernate in the Global.asax file. So how do I configure the session before handing it Ninject if I am using the Web Activator class? Do I just do it like normal in the global.asax?,
Bob Cravens has a nice series of posts on how to do this:
Using the Repository Pattern with MVC and NHibernate
http://blog.bobcravens.com/2010/06/the-repository-pattern-with-linq-to-fluent-nhibernate-and-mysql/
Using an IoC container (like Ninject) with a NHibernate inside ASP.NET MVC
http://blog.bobcravens.com/2010/07/using-nhibernate-in-asp-net-mvc/
Any responsible web developer knows that managing / disposing of objects and resources is critical to good web application development. Please make sure and read this bit too :-)
http://blog.bobcravens.com/2010/11/using-ninject-to-manage-critical-resources/
I don't know which example you are refering to. But for most of them you can do it the same way.
Now, in App_Start folder you have a file called NinjectMVC.cs, there is a method:
private static void RegisterServices(IKernel kernel)
{
}
You have to register all your services there, just the same way you did in global.ascx before.
While developing web project using ASP.NET MVC, I came up against a coupling problem.
When I build custom controller factory (or dependency resolver if using MVC 3), I need this factory to know somehow where to get dependencies from. Here's my code:
//from Global.asax.cs
DependencyResolver.SetResolver(new StructureMapControllerFactory());
class StructureMapControllerFactory: IDependencyResolver {
Container repositories;
public StructureMapControllerFactory()
{
repositories = new RepositoriesContainer();
}
//... rest of the implementation
}
class RepositoriesContainer: Container
{
public RepositoriesContainer()
{
For<IAccountRepository>().Use<SqlAccountRepository>();
//...
}
}
StructureMapControllerFactory class is responsible for injecting dependencies into a controller. As I said, it needs to know where to find these dependencies (I mean concrete classes, like services and repositories implementations).
I have a separate class library called MySite.Data, where all the implementation details live. Contracts, like IAccountRepository, live in library MySite.Contracts. Now, if I reference this MySite.Data library directly from MVC project, there will be a dependency between my site and implementation of its data retrieval. The question is how can I remove it? What are best practices in this situation?
I'm sure it does have a bunch of workarounds, just I haven't found any yet.
Well, as I see it, you can't do exactly that. Your MVC project really really needs to know about concrete classes it is going to use.
You will anyway have to provide those container registrations somewhere and you'll get the dependency on the project/assembly where that type is defined. Shortly, you have to reference MySite.Data from MVC project. Like that:
MySite.Data knows nothing about MVC project
MVC project knows the concrete repositories types to provide correct container registrations.
You can make life simpler with StructureMap Registry objects but you need to include those Registries somewhere as well. Typically those are in the main project or some "StructureMap-adapter" project but you'd need to make reference anyway.
I'd advise that you:
Use MVC3 and drop your custom IControllerFactory if you only use it for DI into your Controllers.
Use StructureMap Registry objects to provide each and every IoC registration ever needed.
Use StructureMap Assembly scanning capabilities to provide components discovery.
Use something much more common as a DependencyResolver, i.e. not a StructureMapControllerFactory but a CommonServiceLocator with StructureMap adapter instead.
Try to abstract from StructureMap itself inside your main app.
And, of course, don't be afraid of making references inside the main project - they have nothing about coupling. It doesn't decrease maintainability. But the wrong architecture does, so be worried about that, not simple reference.
My app is set up this way
Web
Data
Services
POCO Entities
Controllers use services (so they should be injected)
Services use Repositories (which I assume should also be injected)
I have this already set up so that the Controllers receive the service they need through Ninject but I not sure how to get this done with the services =>repositories
any help with this?
You could use the ninject.web.mvc extension. It contains a sample application which illustrates how you could register the container in Global.asax.
Bob has several blogs about repository pattern with Ninject and NHibernate. It's pretty much the same for all other OR Mappers:
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/
Simply set up your services' dependencies as well as the controller's dependencies. Ninject will walk the dependency chain and resolve all of them.
for example,
ProductController has dependency on IProductService
IProductService is implemented with ProductService that has a dependency on IProductRepository
IProductRepository is implemented with NHibernateProductRepository that has a dependency on ISession.
when your NinjectControllerFactory attempts to resolve ProductController, it sees the dependency on IProductService. it resolves that dependency as ProductService, and sees that it has a dependency on IProductRepository. and it will continue on down the chain until it can resolve completely an argument.
so the important part is to Bind ANY dependencies, not just those in a Controller.