design pattern for adding a web service in ASP.NET MVC3 - asp.net-mvc

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)
{
// ...
}

Related

ASP.NET MVC dependency injection outside the controller with Unity

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.

How does ASP.NET 5 inject startup's dependencies?

I'm studying ASP.NET 5 documentation (It's great and better than the old one.) I understand that ASP.NET 5 includes a simple built-in inversion of control (IoC) container that supports constructor injection by default. As far as I know, configuring services and dependencies are done inside ConfigureServices() method.
The ConfigureServices() method is called after StartUp method.
So my question is: how does ASP.NET 5 internally inject Startup's dependencies?
I'd like to know that because if I want to inject another dependency, for example IFooEnviroment how can I do that?
The logic for this lives in the Hosting layer of ASP.NET 5:
the Startup type is determined
the hosting layer registers the required runtime services in the IServiceCollection
An internal service provider is build
an instance of the Startup class is created
You can of course register your own services in ConfigureServices. But they won't be available in the constructor as you already figured. There is no way to add your own services to the runtime services. This makes sense because there should be a difference between runtime services and application services.
You can however inject services registered in the ConfigureServices() method in the Configure() method.

How do I get Unity to inject a reference to HttpSessionState to a service

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.

SignalR and AspNetHost.DependencyResolver

I'm using SignalR in the application I am writing, but I'm confused by examples like the last example at https://github.com/SignalR/SignalR/wiki/Hubs in particular the use of AspNetHost.DependencyResolver
IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
dynamic clients = connectionManager.GetClients<MyHub>();
If I'm not mistaken this is a Dependency Injection tool? Problem is I'm using StructureMap for everything else, and I'd rather not have two dependency Injection frameworks.
Is AspNetHost.DependencyResolver necessary?
SignalR has a bunch of dependencies/services that it needs to function, and it gets those through a DependencyResolver.
You can replace that resolver with your own (e.g StructureMap, Ninject etc.), but if you don't, SignalR will use it's default resolver.

Using Common Service Locator outside Main Project

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.

Resources