Why is MVC4 using the Service Locator Anti-Pattern? - dependency-injection

After reading "Dependency Injection in .NET" by Mark Seemann I stay away from the Service Locator which is an anti-pattern.
Upon reading the release notes on MVC 4 I see:
Improved Inversion of Control (IoC) via DependencyResolver: Web API
now uses the service locator pattern implemented by MVC’s dependency
resolver to obtain instances for many different facilities.
Thus I'm left curious and confused why Microsoft would use a service locator in 2012.

That's an implementation detail that you shouldn't care about. The important thing is that now that the Web API uses the DependencyResolver to resolve dependencies for many different facilities, you will be able to use a real dependency injection whenever you want to plug into those facilities. So in your code you will be using a real dependency injection. If Microsoft didn't use the DependencyResolver then it would have been you that must have used it (as a service locator anti-pattern) in your code in order to resolve dependencies when you want to implement some custom functionality. This would have been bad for you. Now it's bad for Microsoft but you don't care about them.
Thus I'm left curious and confused why Microsoft would use a service locator in 2012.
Because designing a framework is not the same as designing an application using a framework. There are some different things to take into consideration when designing a reusable framework such as ASP.NET MVC rather than just what's written in the books. Some example is to design the framework in such a way that a person using this framework will be able to take advantage of the best practices written in the books in his code using this framework.

As Darin points out, ASP.NET MVC 4 is a Framework and is container agnostic. That's why it provides a service locator in the form of IDependencyResolver. This allows anyone to plug in their container of choice.
However, I wouldn't call this an anti pattern. This allows you to use the container of your choice, but it doesn't force you the application developer to use service location. If the framework forced the developer to use Service Location, then I would call it an anti-pattern. But the developer who builds an ASP.NET MVC application is free to use DI via constructor injection, property setup, or service location. It's their choice.
Look at all the ASP.NET MVC examples of dependency injection published by me or the ASP.NET MVC team. In pretty much all cases, they're using constructor injection. They're not using service location.
In fact, most of the ASP.NET MVC source code itself doesn't use service location to retrieve dependencies. There's a few key places where the MVC calls into the service locator for legacy APIs and such. But that's about it.

Related

How can I automatically register services in .net core dependency injection?

My team is looking at converting our solution to .net core and we are trying to decide whether we should stick with StructureMap as our DI tool or use Microsoft's one that is provided with .net core. One thing we have with StructureMap is the ability to automatically register our services based on naming conventions (something like this):
Scan(s =>
{
s.WithDefaultConventions();
s.AssembliesFromApplicationBaseDirectory(AssemblyFilter);
});
Is there a way to do this with Microsoft's DI container out of the box?

Proper SimpleInjector configuration for WebApi and UnitOfWork Pattern

I have read through the SimpleInjector documentation a few times. But have a few questions.
Context:
3 tier app (presentation (mvc + api controllers), service (business logic), data (repositories, entities, etc)
Unit of Work is a thin wrapper around EF's DbContext
my DbContext and Unit of Work are registered PerWebRequest, using
RegisterWebApiRequest causes an exception, because the Unit of Work is used
outside of Web API requests.
my MVC and Api controllers registered using RegisterWebApiControllers(GlobalConfiguration.Configuration) and RegisterMvcControllers(Assembly.GetExecutingAssembly())
Each controller has one or more services injected into it.
Each service has one or more repositories injected into it.
A service may also have another service injected into it.
I want the same Unit Of Work/DbContext to exist in all my services/repositories.
Questions:
Because I am using services in my MVC controllers as well as API controllers; does that mean I can not use RegisterWebApiRequest in place of RegisterPerWebRequest?
none of my services, repositories, etc, maintain any state, I would get the same functionality using PerWebRequest as Transient; is there any advantage to using PerWebRequest over Transient?
Please read the following q/a: How to configure simple injector container and lifestylse in a MVC web app with WebAPI, WCF, SignalR and Background Tasks. The answer explains that:
Putting your Web API in the same project as your MVC controllers is a bad idea from an architectural perspective.
But if you want to do this, you can use the WebRequestLifestyle in both type of applications. The WebApiRequestLifestyle is meant as lifestyle that works for Web API for both IIS and self-hosted environments, but since you placed the Web API controllers in the same project, you are clearly only interested in IIS-hosted; in that case the WebRequestLifestyle will do just fine.
Because I am using services in my MVC controllers as well as API controllers; does that mean I can not use RegisterWebApiRequest in place of RegisterPerWebRequest?
Both lifestyles use a different way of caching. The WebRequestLifestyle uses the HttpContext.Current.Items dictionary to store its SimpleInjector.Scope instance, while the WebApiRequestLifestyle uses the CallContext class to store the Scope during the lifetime of a single asynchronous operation.
Just as the WebRequestLifestyle can be used while resolving Web API controllers, you can use the WebApiRequestLifestyle (or the underlying ExecutionContextScopeLifestyle) for MVC controllers as well. But if you want this, you will create your own IDependencyResolver implementation for MVC that will explicitly start and end an ExecutionContextScope. The absense of a Scope stored in the CallContext is the reason resolving MVC controllers fails when registering services using the WebApiRequestLifestyle. But while it's possible to use the WebApiRequestLifestyle in MVC, the otherway around is much easier, since no custom code is required.
none of my services, repositories, etc, maintain any state, I would get the same functionality using PerWebRequest as Transient; is there any advantage to using PerWebRequest over Transient?
If services don't have state, it doesn't matter what lifestyle they have. The only restriction is that they have dependencies that have a lifestyle that is equal to or longer than their own. Violating this restriction is called Captive Dependencies and can cause all kinds of trouble. Because captive dependencies are bad, Simple Injector v3 checks and prevents this for you.
Although you can probably make all objects in your configuration scoped (non-transient), making them transient is usually easier to configure, and might result in better performance (although you will probably never notice the difference in real life).

KooBoo & Servicestack Architecture / Design questions

I wanna use KooBoo for my web platform and for that combine it with Servicestack (Servicestack).
Servicestack should act as the REST API framework and Kooboo as the user frontend framework.
I would like to build a independent service layer within that, where Kooboo controllers and servicestack services are leliyng on and share for instance the same session.
So my questions are
How to integrate a webservice framework in Kooboo in general (Change
source, Module, Plugin...)
How to use / integrate layered architecture ? (Because you persist Models directly with your data API, is there a way or what is the recommended way of usinf business objects and ViewModels separated)
Can I integrate other editors instead of tinyMCE
When I use other js framworks like angularJS or kendoUI, can I still use the "inline edit" functions ?
I know, a lot of questions. If you want me to split up these into separate threads I will do that of course!
I've never heard of KooBoo before but seeing that it's built on ASP.NET MVC, the ServiceStack Integration and MVC Integration docs shows how you can access ServiceStack's dependencies, plugins, execute Services etc. from outside of ServiceStack, e.g from within ASP.NET MVC.
The documentation goes through to explain different ways you can integrate with ServiceStack from an ASP.NET MVC web application and also includes a live demo of different techniques at http://mvc.servicestack.net (source code).

MVC web service in .Net

Is there any use to work in MVC web service instead of asmx and WCF web service. Can anyone please tell the difference between the three?
About WCF web services and ASPNET Web Services (ASMX), You can find side by side comparision from MSDN : Comparing ASP.NET Web Services to WCF Based on Development
If you are making MVC Application you can use both ASMX and WCF web services, But I strongly recommend to use WCF Web service for any new development.
For information, I think the more suitable Blog regarding comparison is : ASMX Vs WCF
WCF vs. ASMX
Protocols Support
WCF
HTTP
TCP
Named pipes
MSMQ
Custom
UDP
ASMX
HTTP only
Hosting
ASMX
Can be hosted only with HttpRuntime on IIS.
WCF
A WCF component can be hosted in any kind of environment in .NET 3.0, such as a console application, Windows application, or IIS.
WCF services are known as 'services' as opposed to web services because you can host services without a web server.
Self-hosting the services gives you the flexibility to use transports other than HTTP.
WCF Backwards Compatibility
The purpose of WCF is to provide a unified programming model for distributed applications.
Backwards compatibility
WCF takes all the capabilities of the existing technology stacks while not relying upon any of them.
Applications built with these earlier technologies will continue to work unchanged on systems with WCF installed.
Existing applications are able to upgrade with WCF
New WCF transacted application will work with existing transaction application built on System.Transactions
WCF & ASMX Integration
WCF can use WS-* or HTTP bindings to communicate with ASMX pages
Limitations of ASMX:
An ASMX page doesn’t tell you how to deliver it over the transports and to use a specific type of security. This is something that WCF enhances quite significantly.
ASMX has a tight coupling with the HTTP runtime and the dependence on IIS to host it. WCF can be hosted by any Windows process that is able to host the .NET Framework 3.0.
ASMX service is instantiated on a per-call basis, while WCF gives you flexibility by providing various instancing options such as Singleton, private session, per call.
ASMX provides the way for interoperability but it does not provide or guarantee end-to-end security or reliable communication.
I can't top the other post on here regarding the merits of WCF over ASMX, it is from the source (microsoft), what I would add to that post as it fails to mention the MVC Web API, is this... your question really depends on the problem you are trying to solve. If you are trying to do messaging, message queues, or lower level tcp/ip it will still be WCF..
I'm a modern world programmer, as lazy as they come.. both ASMX and WCF technologies are starting to feel a bit dated to me, for example a typical WCF implementation will probably have a hefty XML configuration associated to it, if this is the way you are used to working then it will probably feel natural.
I like type safety and hate magic strings and further hate digging around in large XML, to my mind this is the path of the runtime error.
If you have used the MVC framework to create a web application then there is pretty much a zero learning curve to using the mvc webapi.
All the standard things like routes, models and controllers still apply in exactly the same way, all the HTTP verbs are there to be used...
With minimal effort all your routes and controllers can be used in a completely type safe way (no strings), so if it is broken then it probably doesn't compile....
Also it is much easier to write a unit test to exercise a controller than it is to unit test a ServiceContract
I'm not certain but I'd expect the MVC route to lend itself to IoC/DI better than WCF for the same reason above, but I'm prepared to be wrong on that.
Can you tell I'm biased.
This is a subjective question and with regards to the difference between the 3; WCF is more suited to communication between layers, asmx is basically what we used before wcf came along and due to the flexibility of mvc, it can be used in a number of senarios. WCF is however great for implementing OData services.
I personally use MVC to implement the web service on the client tier for AJAX interactions and have done so on several projects. The advantages are that I do not have a separate project and as such the front end stack is light weight and DRY, more efficient and organising code in this way makes more logical sense to me.
IMHO wcf has too large an overhead and is overly complex for simple JSON serialization. I personally think there is a case for using MVC in an n-tier architectural site instead of WCF.
This article looks at using this in the infamous NerdDinnerd project nerd dinner rest
There are several frameworks such as OpenRasta, but I find that the standard mvc.net tools are more than sufficient.
Also, a good article by haacked here: haacked.com
I'm on the core team that maintains ServiceStack - another very popular choice to build REST-based services on .NET / Mono.
Supports REST, SOAP and MQ based services
In addition to REST-based services you can re-use your same services to Support both SOAP and REST-based endpoints. ServiceStack also includes the .NET's fastest JSON, JSV and CSV text serializers. Here's an earlier answer comparing its advantages over WCF and WebApi.
Succinct, Typed, End-to-end API
ServiceStack also includes typed generic ServiceClients in all the major supported formats including: JSON, XML, JSV, SOAP 1.1/1.2 as well as the super fast binary ProtoBuf and MessagePack formats.
ServiceStack's generic service clients offer the most succinct, typed end-to-end client/server API without any code-gen.
ServiceStack Overview slides
The ServiceStack Overview Talk at this years MonkeySpace has a good intro into ServiceStack and its advantages.

ASP.NET MVC consuming WCF

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.

Resources