I recently made the jump from StructureMap to Ninject. All was smooth sailing until I realised that Ninject doesn't have a version of StructureMap's ObjectFactory (service locator).
I discovered Common Service Locator which provides the Service Locator Pattern with any IOC container including Ninject. It works great inside my 'start-up' project - e.g. WebSite. But if I try to access ServiceLocator.Current from subprojects, e.g. Core or Data it seems that CommonServiceLocator doesn't know about any of my Dependency mappings.
How do I use Common Service Locator from a sub-project?
N.B. I am aware of the debate about ServiceLocator as a pattern/anti-pattern. I've found that there is a trade-off between ServiceLocator as an anti-pattern and Anaemic Domain Model as an anti-pattern - sometimes its just much easier & maintainable to use a service locator.
Use factories instead of accessing the container directly. This keeps your application free from a specific container and prevents the usage of a service locator.
The only situations where you have to access the kernel is once in your composition root and in some very rare situations where you aren't in control of the object creation. In these situations you can still assign the kernel to a singleton object or use the ServiceLocator to make it accessable from anywhere.
ServiceLocator is a static object. Therefore there is no difference from where you are accessing it. I assume that you are accessing the ServiceLocator before it is fully confugured.
Without entering the debate on the use of a service locator, have you tried this NuGet Package CommonServiceLocator.NinjectAdapter?
When I decide I want one, this is what I've used.
Related
I am building an ASP.NET MVC 5 application using the repository and service layer design patterns. I have used unity to inject my services into my controllers.
This works nicely and until now I have not had a need to consider instantiating any objects requiring injection of interfaces outside my controllers. However I have a need for this when configuring my application startup to setup some users in the database.
For this I wanted to user my UsersService that I've built. And it occurred to me as the application grows there will surely be other occasions when I'll want to do the same, such as calling a service from within another service.
I see that I can instantiate a Unity container and call resolve on it to get my new instance of a service:
IProductService productService = container.Resolve<IProductService>();
However this kinda smells to me, having the container leaked all over my application seems like an anti pattern. So is there a better way to do this?
Unity and other dependency injection containers automatically do this. When you inject a service into a controller, it will automatically resolve the entire dependency graph of that service. Not only can you resolve dependencies of the service and its dependencies, you should inject dependencies into the service that needs them instead of the controller.
Any class (including the controller) that has more than a handful of dependencies is a code smell that you are violating the Single Responsibility Principle, and you most likely should refactor to aggregate services.
And yes, injecting the container to any point outside of the composition root is an anti-pattern called a service locator.
As for injecting services outside of the controller, it is important to distinguish between injectables and runtime data. For example, some try to inject services into DTO objects, attributes, static classes/extension methods, and other places where it is anti-pattern for services to be injected. For these situations, it is important to properly assess the situation and refactor toward a DI-friendly solution - favoring constructor injection over other alternatives and considering a service locator as a last resort. For example, if you are trying to make an extension method with a dependent service, most likely you have some functionality that itself should be a non-static service, DTOs should never be created from a DI container, and you may have to make use of more than one extension point in MVC where you inject the container within the composition root of the application, which does not constitute a service locator.
Is it worth it? Usually. What is gained? You gain the ability to change the application much more quickly than if you have a tightly-coupled application in ways that the designer of the application may not have even anticipated. So the extra cost of ensuring the application is loosely-coupled is usually more than recouped in ongoing maintenance of the project. As a side benefit, you gain the ability to easily unit-test each component independent of the others.
Disclaimer: I have a fair bit of experience with DI containers but am quite new to Unity.
I have an MVC project that is all wired up with Unity DI using constructor injection and works great. But I now have a service that I want to inject into my controllers (and maybe places other than controllers at some point) and this service needs access to ASP.NET session state. The service's purpose is to manage a list in session and I don't want the list mechanics in my controller.
I realize I could add a Setup method to the service (and it's interface) that my controller could call, passing in a reference to the Session, before using the service, but I don't like that as I may want to make an implementation of the service that uses something other than Session for my state management and also it is implementation specifics leaking into my interface. I also realize I can use HttpContext.Current in my service but I don't want to do that for many reasons, particularly for the issues it creates for unit testing.
Can Unity inject a reference to HttpSessionState into the service's constructor?
There's a couple ways to do this. The easiest is probably to use an injection factory:
container.RegisterType<HttpSessionState>(
new InjectionFactory(c => { return HttpContext.Current.Session; }));
Then anywhere you have a dependency on the HttpSessionState in the graph, the delegate given will run and pull it out of HttpContext.Current.
Of course, this only works if you're doing a new resolve per request.
I'm using Autofac to implement IoC in my solution, But I am doubtful whether I'm doing it right or not. Here's the scenario:
I have some Manager classes which all derive from BaseManager class. The BaseManager has a protected User CurrentUser field. What I'm trying to do, is to resolve the CurrentUser using Autofac. I have written anIUserProvider interface and implemented a couple of classes (e.g. WebUserProvider and WinformsUserProvider).
Then I registered my provider as below (for example, in Global.asax):
builder.Register(c => new WebUserProvider(...)).As<IUserProvider>();
How can I resolve dependencies (access container in my classes)? I could use a singleton or a service locator pattern but seems like it's an anti-pattern. So how should I resolve my dependency?
This sounds like overengineering to me. Why would you have a base manager class that has knowledge of the user? Having a few manager classes is a code smell and a maintenance hazard on its own, as your are abstracting too much. Do you really need that?
How can I resolve dependencies (access container in my classes)?
You should not be looking for a way to access your container. Container must be initialized once, in a single place. You should inject all the dependencies via constructor. These dependencies are passed in from the root of the dependency graph using container.Resolve<T> and elsewhere in the dependency graph using constructor injection (or some folks use property injection).
Firstly - I'm not asking this question How to host a web service in MVC3? I know where the button is :-)
I'm trying to find an example of best practices of how to use the new DI / Common Service Locator framework in order to make web service calls (and code dependent on web service calls) testable. I've no experience of using NInject or the like - is that the way to go?
Pretty much the same way one deals with any external depenency -- wrap it up in an interface, make the controller take an instance of the interface as a constructor parameter. Implementation-wise, you can handle things a number of ways, we have typically made the service wrapper take the service as a dependency and let structuremap worry about lifecycle. Not horribly familiar with NInject so I'm not sure if there is a better way there but I'd suspect they have similar capabilities.
I don't know what is the best practice but I think you can do this with Windsor's WCF facility (Ninject has a WCF extension as well). Register your service, then set your dependency resolver and let MVC's dependency resolver to do the hard work, constructor injection for example:
Register your service:
container = new WindsorContainer().AddFacility<WcfFacility>();
container.Register(Component
.For<IService>()
.On(WcfEndpoint.FromConfiguration("...")))
.LifeStyle.Transient);
Set dependency resolver:
DependencyResolver.SetResolver(new WindsorDependencyResolver(container));
Then MVC3's new dependency resolver should be able to inject your service proxy into the constructor, for example:
public HomeController(IService service)
{
// ...
}
My ASP.NET MVC 2 controllers are currently instantiating service objects in their constructors by passing repository instances that are instantiated by Castle Windsor. I have unit tests that call the controller actions after passing Moq instances of the repositories to the controller's constructor.
I want to allow a third-party UI to access these service objects through WCF.
It occurred to me that converting my existing Service layer into Web services or even adding a new Web service layer between the UI and the existing Service layer will break my unit tests unless I find a way to bridge that gap.
I was trying to work out a solution where my UI was coded against an interface of the service layer (it already is) and I could use DI to pass the Web service implementation at run-time and pass the existing implementation during unit testing. The Web service implentation would simply call the existing implementation.
Questions:
Is such an approach advisable / possible?
Are there any examples of this in a tutorial or open source project?
EDIT:
I believe I have a workable solution now thanks to the suggestions below. I created a WCF Service Application that uses the existing service interfaces from my domain model. The WCF implementation is a class where the constructor takes repository instances from Ninject's WCF extension and creates an instance of the service from the domain model. Each method/function in WCF simply calls the same method/function from the existing service layer.
There were some caveats. For example, I can no longer pass a reference to my ASP.NET MVC ModelState when I create the service in the controller (actually, I use Ninject to create an instance of the WCF service and supply that to the controller's constructor). The reason is that WCF is a messaging platform - changes must be explicitly communicated back with each call (i.e. my validation errors are now communicated back as reference parameters on individual functions/methods).
I also had to add some serialization/servicemodel references to my formerly POCO Core project.
Also, I switched from Castle to Ninject because Castle's WCF solution has a maturity level of low and I wasn't comfortable using that at this time.
Can you explain in more detail why your tests would break?
I do this type of development all the time. Services as classes => services as WCF services.
Your tests shouldn't break. A WCF Service is almost 100% contract, the underlying business code and logic shouldn't have to change.
Check out the Web Services Software Factory created by the Patterns & Practices team. It is a good way to structure your services into contract projects (data, message, service) and "business code". Once you get a better understanding of how to structure your code, you can refactor their style to something that fits you a little better. Their example tends to separate everything into lots of VS projects, which can be a little overkill for most shops. Example, I don't see many shops sharing data contracts across projects. Yes, in a perfect world, you should probably share a lot os types (like address) across projects, but I don't see it done very often. So, I tend put all my contract stuff in one VS project.
If your services are already defined as interfaces then you've got a head start.
Pass the services into the controllers as constructor dependencies, rather than the repositories. Let your DI container A) provide the repositories to the services, and B) provide the services to the controllers.
If you want to stand up your service layer as wcf services to be accessed by other applications, you'll want to use the wcf service factory to pull the concrete service implementations out of your DI container. Here's an example with windsor, it should be easy to adapt to whatever container you use.
At this point you can modify your website to either A) continue to invoke the services directly, or B) have them call back to the web services using service clients. There are pros and cons to both methods.