Recently I faced this problem where an ASP.Net MVC website with Autofac as DI was working fine in my local IIS but when I published it in Azure, it was not getting redirected to the default controller, instead it was showing me the welcome page.
I did a lot of things to finally know what was the problem like checking the web.config file line by line.
Is there any easy mechanism to catch DI failures in production / published environment?
It is no easier mechanism for Autofac specifically, than what you would need to debug the rest of the application. Logging is the first tool you should implement. Given that this is a production environment, you probably already have some form of logging infrastructure in place.
Resolve failures in Autofac (e.g. when Autofac is unable to fulfill constructor parameter requirements) causes exceptions, which unless handled explicitly, can be handled and logged at the application level using the Application_Error event handler.
In case there are no exceptions, or exceptions are swallowed somewhere in the MVC stack, you could hook up to the container Scope and Resolve events and log the activity. That way you can get a picture of what Autofac is doing in the production environment. This SO question discusses both container events and component registration events.
The way to do this is by verifying if all root registrations can be created. You can create a unit test that loops over all registrations and try to resolve them one by one. Being able to do this is very important, since with DI the application code itself isn't responsible for maintaining the dependencies between implementations, and the compiler will therefore not be able to verify whether the dependency graph is correct. Although it is impossible for the compiler to verify the dependency graph, verifying the dependency graph is still possible and advisable, because not doing this will force you to click through the complete application and eventually leads to the situation you got yourself into.
Unfortunately, I found that this is actually very hard to do with Autofac. I pretty sure that this should be possible, but I never got this working. Some other DI containers make it considerably easier to verify the container's configuration and check for other common configuration mistakes.
Related
I am writing MVC UI wrapper reusing legacy core libraries that were written down for desktop edition using Autofac for DI. The problem I am facing is, core libraries are working with Lifetime scope that I can't change while MVC requires InstancePerRequest.
So what happens is, in MVC, if I register my services for InstancePerRequest scope, they get disposed by core libraries before request completes. It makes MVC application unhappy.
I tried using LifeTimeScope for all services in MVC app too. Since Lifetime scope is shorter than Request life, it appears to work in MVC.
Is there any downside in this approach?
Note: In legacy code all the time services are being resolved manually, instead of being injected through constructor. Like:
using (var scope = IocContainer.BeginLifetimeScope())
{
var service = scope.Resolve<IMyService>();
return service.FindAll();
}
MVC will work with InstancePerLifetimeScope for services as noted in the documentation about sharing registrations across apps that have and apps that don't have request scopes.
I think there are going to be potentially two gotchas in your approach to creating your own lifetime scope. Whether you can live with them is very much app specific so you'll have to judge for yourself.
Problem 1: Early Disposal
In your example you show a factory or service IMyService being resolved, doing some work, and returning that work. At the end of the using statement the owning lifetime scope is getting disposed. That means IMyService will be disposed (if it's IDisposable) and any dependencies that IMyService requires will also be disposed. In the case of things like database contexts or connections, that well could mean the return value becomes invalid because you won't be able to update the values or read additional data against a disposed connection.
Problem 2: Singleton/Sharing Issues
Lifetime scopes are sometimes used to isolate units of work or sets of components that need shared context. For example, in MVC you only have one instance of the controller for the whole request - no matter how many times you resolve the controller object, for that request it'll be the same instance. You might see a similar thing with database connections - one connection from the pool allocated for an entire request lifetime.
By creating your own lifetime scope you are also creating a sort of logical unit of work. Any dependencies for IMyService will not be shared with the rest of the MVC request. In fact, it's more like that tiny lifetime scope is its own request or its own unit of work. No overlap.
General Resolution
As noted in the doc I linked to earlier, register things as InstancePerLifetimeScope if they need to be used in both MVC and non-MVC contexts and just let the MVC request semantics handle spinning up and disposal of scopes if possible.
If that won't work, it'll be up to you and your app code to figure out if you can live with the issues here or if you need to address them. If you need to address them, that, too, will be app specific so there isn't "guidance" to provide - you're on your own for that.
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.
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).
We are using both Angular and Rails applications at our company. Is there a way to mock a web page to test the UI? Essentially I want to jump midway into an application, so I don't have to take time logging in, creating our object, tweaking the object, then finally getting to what I can test.
I was looking at something like MSL, but am unsure if it's really what I need.
Turns out MSL is what I wanted. My application depends on other applications for communication. In order to isolate my isolation, I can use MSL to mock the responses from and the requests to my dependent applications fairly easily. In my configuration I switch my external dependency to localhost:8001 (or whatever port msl is running on).
Edit
I rewrote MSL, specifically for my purposes and made it a little easier. The server is a node program, and the client is only in ruby as of now.
mobe-server
mobe-client
Lets say; I am developing a Web Application which talks to a RESTful web service for certain things.
The RESTful web service isn't third party, but is being developed parallely with main application (A good example would be, E commerce application and payment processor; or Social network and SSO system).
In such a system, acceptance(cucumber) or functional tests can be done in two ways:
By mocking out all external calls using object level mocking library; such as Mocha or JMock.
By doing mocking at http level, using libraries such as webmock.
By actually letting the main application make the actual call.
Problem with #1 and #2 is, if API of underlying application changes; my tests would keep passing and code will actual break and hence defeating the purpose of tests in first place.
Problem with #3 is, there is no way I can do rollback of data, the way test suite does on teardown. And I am running my tests parallely and hence if I let actual web services go, I will get errors such as "username taken" or stuff.
So the question to community is, what is the best practice?
Put your main application in a development or staging environment. Spin up your web service in the same environment. Have the one call the other. Control the fixture data for both. That's not mocking; you're not getting a fake implementation.
Not only will this allow you to be more confident in real-world stability, it will allow you to test performance in a staging environment, and also allow you to test your main application against a variety of versions of the web service. It's important that your tests don't do the wrong thing when your web service changes, but it's even more important that your main application doesn't either. You really want to know this confidently before either component is upgraded in production.
I can't see that there is a middleground between isolating your client from the service and actually hitting the service. You could have erroneously passing tests because the service has changed behavior, but don't you have some "contract" with the development team working on that service that holds them responsible for breakage?
You might try fakeweb and get a fresh copy of expected results each day so your tests won't run against stale data responses.