In my web.api application I use EntityFramework 6 (EF6), MediatR, and Autofac. I want to Create EF6 DbContext with a lifetime matching MediatR RequestHandlers so that I obtain a unit of work per RequestHandler invocation.I've been looking into Autofac concepts like InstancePerMatchingLifteTimeScope, Owned< Dependency > and also MediatR Handler Decoration using MediatR Pipeline.
I haven't found any solution yet. It seems I need to wrap both Handler Creation and handler invocation inside a AutofacLifeTimeScope tagged with a wellknown-object, so I can register IDBContext with InstancePerMatchingLifeTimeScope(wellknown-object).
Maybe You can propose another solution ?
Related
Is it possible to use middleware in the newest Azure Functions (with .NET 5) to register a new service with DI that is scoped to the function call?
I want to use this so that I can inspect the function context and add add some tenant-specific services that can be injected to the function class's constructor.
Alternatively, could I add a service or object that is injected into the function's method as an argument.
// Method injection would look like this:
public Task MyFunction(FunctionContext context, ITenantSpecificService service)
{
// service would be set in the middleware
}
I can manually create an object and add it to the FunctionContext.Items, but that's just not as clean as using the dependency injection system built-in to Functions.
I simply cannot figure this out. Using Autofac with .Net core 2.0 and trying to resolve some simple dependencies. Feel like I've tried everything so my current code doesn't reflect everything I've tried.
Here is one of the exceptions I'm getting from Autofac
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type
'Elucidate.Core.Application.ValuesController' can be invoked with the available services and parameters: Cannot resolve parameter 'Elucidate.Core.Data.Repository.IRepository'1[Elucidate.Core.Model.User.IUser]rep' of constructor 'Void .ctor(Elucidate.Core.Data.Repository.IRepository`
Here is where I'm trying to get the dependency injected
public ValuesController(IRepository<IUser> rep)
Here is how I'm registering the types in an autofac module
builder.RegisterType<User>().As<IUser>();
builder.RegisterType<CoreUserStore<User>>();
builder.RegisterType(typeof(Repository<User>)).As<Repository<IUser>>();
builder.RegisterType<EntityFrameworkModelContext<User>>(); //.As<IModelContext>();
What am I doing wrong? I'm new to autofac, used to Unity which seems to be extinct.
The ValuesController constructor is expecting IRepository<IUser> and you haven't wired the correct type in Autofac.
You need to register the concrete repository type as the implemented interface, note the .As<IRepository...:
builder.RegisterType(typeof(Repository<User>)).As<IRepository<IUser>>();
Or alternatively "ask" for the concrete type in the constructor.
public ValuesController(Repository<IUser> rep)
The first is probably the preferred approach. You can also do:
builder.RegisterType<Repository<User>>().AsImplementedInterfaces();
Which will register the concrete type as all implemented interfaces.
If I have a class HelperClass that I'd like to use within a saga, I'd like to be able to inject an IHelperClass into the constructor.
The problem I'm running into is that sagas appear to be instantiated with an empty constructor; so while I can create a constructor that takes IHelperClass and use it in unit tests, the framework will always call the parameterless constructor.
I think I could use property injection, but since this helper class is "necessary," my understanding is that property injection (assuming it would work) is not a best practice.
So how can I do this without taking a hard dependency on the concrete HelperClass implementation?
You don't have to worry about the "necessity" of the help object in the context of the saga since no other code will be instantiating the saga directly.
In short, you can use property injection without concern here.
Is there are possibility to instantiate class using ASP.NET 5 default Dependency Injection when that class have constructor with parameters?
I would like to register Repository with constructor that accepts connection_string.
UPDATE
I think that I can rephrase the question. I would like to specify which constructor will be called when the class is being registered. Something similar that Autofac have. Is that possible?
builder.RegisterType<ConfigReader>()
.As<IConfigReader>()
.WithParameter("configSectionName", "sectionName");
Unfortunately, the out of the box DI container does not support parameter constraints. It is all or nothing.
If you want advanced features, you can switch to another DI container, like Autofac, that you already mentioned and that is supported in ASP.NET 5.
I've ran into a rather hairy problem. There is probably a simple solution to this but I can't find it!
I have a custom HttpHandler that I want to process a request, log certain info then enter the details in the database. I'm using NUnit and Castle Windsor.
So I have two interfaces; one for logging the other for data entry, which are constructor injected. I quickly found out that there is no way to call the constructor as the default parameterless constructor is always called instead.
So I thought I would use Setter injection and let Castle windsor sort it out. This actually works as when I use container.Resolve<CustomHttpHandler>(); I can check that the logger is not null. (In Application_Start in Global.asax.cs)
The problem is although Castle Windsor can create the instance the http application is not using it??? I think??
Basically the whole reason for doing it this way was to be able to test the logger and data repository code in isolation via mocking and unit testing.
Any ideas how I can go about solving this problem?
Thanks!
Not possible, at least not directly. IHttpHandler objects are instantiated by the ASP.NET runtime and it doesn't allow Windsor to get involved in its creation. You can either:
Pull dependencies, by using the container as a service locator.
Set up a base handler that creates, injects and delegates to your own handlers (see how Spring does it)
Use the container as a service locator for another service that handles the entire request (as saret explained)
What you could do is have the HttpHandler call out to another object that actually handles the request. so in your HttpHandler's ProcessRequest method you would do something like this:
public void ProcessRequest(HttpContext context)
{
var myHandlerObject = container.Resolve<HandlerObject>();
myHandlerObject.ProcessRequest(context or some state/info that is required)
}