We are currently using autofac in our mvc web app.
Build() or Update() can only be called once on a ContainerBuilder
Every 1-4 days we get the error noted above. It's driving me crazy. I've been trying to see why it would be doing this but I can't pinpoint the issue.
Can someone point me in the right direction.
I encountered the same thing in my application (.Net Core 3.1)
I wanted to get the Container and resolve registered services.
In .Net Core 3.1 you can't simply change Startup.ConfigureServices method to return IServiceProvider as it was in previous versions
So, to get the services you need in your Startup void Configure(IApplicationBuilder app) method call app.ApplicationServices.GetAutofacRoot() this will return ILifetimeScope instance you can use to resolve services
Note. Consider that saving this instance globally is not the best practice
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//app middleware registrations
//...
//
ILifetimeScope autofacRoot = app.ApplicationServices.GetAutofacRoot();
var repository = autofacRoot.Resolve<IRepository>();
}
Unless you have start-up processes that require HttpApplication resources, I would recommend removing application initialization to a static constructor or a completely separate singleton. I have seen similar issues with Application_Start(), you need a structure that is guaranteed to be called just once.
Related
I have a JAX-RS (Jersey) server with which I register and bind my stuff.
I want to print a banner when the server starts up. I want to do this using the JAX-RS framework not the web server's platform (i.e., no Jetty, Netty, Thorntail, etc hooks).
I saw the following which mentions the tried and true Servlet way of doing things:
Jax rs: How can I run a method automatically everytime my server restarts? , but that does not work because I am not running a servlet container in my server so that lifecycle call is never made.
I figured there must be a JCA-ish type object that I can register with Application/ResourceConfig that has such a lifecycle call, but I am unable to even find any kind of list of the things you can actually register.
Not to complain (but I will), but I cannot decide if this is so difficult because when they moved the project to eclipse, they broke every hyperlink to the old official documentation or that it is simply so implicit, like Spring, that it only works by github'ing other people's code and realizing, 'oh, I did not know you could do that'.
Jersey has Event Listeners. You'll want to use the ApplicationEventListener and the ApplicationEvent.Type you'll probably want to listen for to print the banner is the INITIALIZATION_FINISHED
public class MyApplicationEventListener
implements ApplicationEventListener {
#Override
public void onEvent(ApplicationEvent event) {
switch (event.getType()) {
case INITIALIZATION_FINISHED:
printBanner();
break;
}
}
#Override
public RequestEventListener onRequest(RequestEvent requestEvent) {
return null;
}
}
is it Ok if we call wep api service inside web form using api dll. we will be hosting both api and application on same server and requiring internal calling.
It's not very clear what you are after.
First of all if you write an API of some kind then you have to call it to interact with it. There's no middle ground here. If you don't want to call anything then you don't need an API. The purpose of an API is to provide a way to interact with some data storage, so behind your controllers you'd have a layer which talks to a database for example, or even another API.
If you don't want to make any calls then why bother with an API at all? Write a class library, one or several, doing whatever you need them to do and interact with your database this way.
I worked in a project before where I had a somewhat similar situation and ended up writing class libraries which were then shared by a UI project and a WebApi project, so you could work with them either way. This worked quite well actually. If you are looking for something similar then that's what I would go with. Keep the stuff of interest separate so you can expose with an API call or a direct dll reference.
So assuming that your controller methods look something like this:
public interface IService
{
Task<Value> GetValueAsync(int id);
}
public class Service : IService
{
public Task<Value> GetValueAsync(int id)
{
//...
// Code to return a value
//...
}
}
public class ValueController : ApiController
{
private IService _service;
public ValueController(IService service)
{
_service = service
}
public Task<IHttpActionResult> GetValueAsync(int id)
{
return Ok(await _service.GetValueAsync(id));
}
}
Then it is perfectly okay to call the method in the Service class. I would not call the method in the controller as that will cause more problems than you probably want to deal with.
I'm currently evaluating WebAPI and NancyFx for a new project about to start. I've managed to get Nancy to self host from a test assembly (by itself it uses asp.net hosting).
Is there any way to do the same with Web API? I would like to keep the web api project hosted on IIS, but i would like to spin it up from my test assembly, so i can run tests against it.
I have found some blogposts on how to use Autofac to scan controllers from another assembly (seems a little backwards only to get hosting from another assembly to work, but if it can be done, i guess that would be an option), but i would like to keep using Structuremap ioc for this project.
Managed to get it working with help from Mark Jones link. This is what i ended up with in my test assembly.
private static HttpSelfHostServer _server;
[BeforeTestRun]
public static void Setup()
{
var config = new HttpSelfHostConfiguration(Settings.TestUri);
WebApiConfig.Register(config); //map routes
IocConfig.Bootstrap(config); //configure dependency injection
_server = new HttpSelfHostServer(config);
_server.OpenAsync().Wait();
}
[AfterTestRun]
public static void TearDown()
{
_server.CloseAsync().Wait();
}
In normal ASP.MVC projects we configure the dependency resolver with Unity and the Unity.Mvc3 package from http://unitymvc3.codeplex.com/
We have this test service registered with a HierarchicalLifetimeManager
container.RegisterType<ITestService, TestService>(new HierarchicalLifetimeManager());
And we hook up the container with Mvc in Global.asax.cs:
System.Web.Mvc.DependencyResolver.SetResolver(new Unity.Mvc3.UnityDependencyResolver(container));
And we run this test controller:
public class TestController : Controller
{
private readonly ITestService _service;
public TestController(ITestService service)
{
this._service = service;
}
public ActionResult Test()
{
var locatedService = System.Web.Mvc.DependencyResolver.Current.GetService<ITestService>();
if (_service == locatedService)
return View("Success - Same Service");//This is always the result in an MVC controller
else
throw new Exception("Failure - Different Service Located");//This is never the result in an MVC controller
}
}
However, on this project we are adding a number of WebAPI controllers.
We have this configuration in global.asax.cs (using http://unitywebapi.codeplex.com/ for now. But I am open to suggestions):
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
We have created an ApiTestController similar to TestController inheriting from ApiController rather than from Controller.
However, the ApiTestController fails its test. I understand that the System.Web.Mvc.DependencyResolver class and the System.Web.Mvc.DependencyResolver.Current property are specific to Mvc. But does WebAPI have an equivalent?
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver.GetService does not work because the System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver instance is the parent container that I configured. It is not the child controller that was used to inject the ITestService into the constructor.
This user seems to have a similar problem: http://unitywebapi.codeplex.com/discussions/359413
But I feel that this probably has more to do with ASP.NET's WebAPI than it has to do with Unity.
Thanks
After looking over the source of http://unitymvc3.codeplex.com/ and http://unitywebapi.codeplex.com/ I created this class:
public class MyUnityDependencyResolver : Unity.Mvc3.UnityDependencyResolver, System.Web.Http.Dependencies.IDependencyResolver
{
public MyUnityDependencyResolver(IUnityContainer container)
: base(container)
{
}
public System.Web.Http.Dependencies.IDependencyScope BeginScope()
{
return this;
}
public void Dispose()
{
Unity.Mvc3.UnityDependencyResolver.DisposeOfChildContainer();
}
}
Configuration in gobal.asax.cs:
var myResolver = new MyUnityDependencyResolver(container);
System.Web.Mvc.DependencyResolver.SetResolver(myResolver);
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = myResolver;
Unity.Mvc3.UnityDependencyResolver uses HttpContext.Current.Items to manage child containers. MyUnityDependencyResolver may not be the most "correct" implementation of System.Web.Http.Dependencies.IDependencyResolver, but it seems to work so far.
I will mark this as the answer in a couple days if no one else has any better answers.
Unfortunately, when you call the GlobalConfiguration.Configuration.DependencyResolver.GetService, it completely ignores any scope and resolves using the outer non-child container which is around for the lifetime of the application. This is an issue with Web Api and makes it impossible to use constructor injection for per-request dependencies outside of controllers. Confusingly this is completely different behaviour from MVC as you say.
What you can do is use the GetDependencyScope() extension method off HttpRequestMessage. Anything you resolve using this will be in per request scope when using HierarchicalLifetimeManager in conjunction with Unity.WebApi. The request is available from action filters and handlers so may be a viable workaround.
Obviously this is pure service location rather than dependency injection which is far from ideal but I have not found another way to access per-request dependencies outside of controllers.
See this post for more info.
The DependencyResolver is not the right seam for dependency injection in ASP.NET WebAPI.
Mark Seemann has two really good posts on DI with WebAPI.
Dependency Injection and Lifetime Management with ASP.NET Web API
Dependency Injection in ASP.NET Web API with Castle Windsor
If you want to do it right you should have a look at them.
I'm trying to get myself familiar with MVC3 and autofac but I've encountered small problem that I'm having trouble resolving.
I am using autofac integrated with MVC3 and all works well, pages are loading correctly, dependencies are being injected and that's cool. What's bugging me is how to use autofac's Container or MVC's DependencyResover in class library project.
I'm trying to create static class that will help me handle domain events. I simply want to be able to call the method with event parameter and everything should be handeled by this class. Here is code:
public static IContainer Container { get; set; }
public static void Raise<T>(T e) where T : IDomainEvent
{
foreach (var eventHandler in DomainEventManager.Container.Resolve<IEnumerable<EventHandlers.Handles<T>>>())
{
eventHandler.Handle(e);
}
}
As you can see it's pretty straightforward and everything would work great if it wasn't MVC approach. Some of my dependencies are registeres as InstancePerHttpRequest (NHibernate' session), while other are registered as InstancePerDependency or SingleInstance. Thus when I try to use container created in my UI project, I get exception that there is no httpRequest tag available.
How can i reuse the Container created in web project to get access to all of it's features, including InstancePerHttpRequest and httpRequest tag?
Or maybe there is other solution to my problem? I was thinking about using delegate function to obtain event handlers, but I cannot (can I?) create generic delegate that I would not need to initialize with concrete type at time of assignment.
Why I want to do this using static class is basically every entity and aggregate or service needs to be able to raise domain event. Injecting EventManager into every one of these would be troublesome and static class is exactly what would resolve all my problems.
If anyone could help me get my head around it I would be grateful.
Cheers, Pako
You shouldn't be referencing your container directly from your app code. This looks like the Service Locator anti-pattern. The correct action is to pass your objects the services they need to do their jobs, usually done through constructor parameters. BUT... if you are going to insist on depending on a global static, then at least model EventManager as a singleton, such that usage would look like:
EventManager.Current.Raise<SomeEvent>(someObject);
and then you can set EventManager.Current equal to a properly constructed instance when your app is initialized.