My .NET Core / MVC application has 3 service/controller, domain, and data access layer ties. Each API call within the service/controller layer works as expected where the iMyResponse is always injected based on registration. The Domain/DAL initialize
the 1st API call resulting in a singleton approach and not allow transient or scoped service lifetime. What am I missing? This seems very straight forward.
public MyDAL(IMyResponse iMyResponse) { iMyResponse is only called once so the service lifetime cannot be scoped or transient }
services.AddTransient();
I've tried using a middleware approach but get the following error: "Unable to resolve service for type 'Microsoft.AspNetCore.Http.RequestDelegate'"
<div> public MyDAL(RequestDelegate next)</div> <div> {</div> <div> this._next = next;</div> <div> }</div> <div></div> <div> // IMyScopedService is
injected into Invoke</div> <div> public Task Invoke(HttpContext httpContext, IMyResponse iMyResponse)</div> <div> {</div> <div> this._iMyResponse = iMyResponse;</div> <div>
return this._next(httpContext);</div> <div> }</div>
The DAL is using the DAO and DTO patterns. The DTO travels between the Web API client and service. The DAL is sitting behind the WebAPI service and the service is calling on the DAO objects in the DAL for CRUD.
I am trying to understand why the DAL's constructor isn't called during another API call effectively making any DI constructor dependency a singleton. There's no way to change the service lifetime to say scoped or transient.
I've read other approaches such as injecting into a Invoke method ala middleware approach but keep getting the RequestDelegate error above.
I am trying to understand why the DAL's constructor isn't called during another API call effectively making any DI constructor dependency a singleton. There's no way to change the service lifetime to say scoped or transient.
I've read other approaches such as injecting into a Invoke method ala middleware approach but keep getting the RequestDelegate error above.
It seems to be overly complicated.
If you find the post has answered your issue, then please mark post as 'answered'.
I am trying to understand why the DAL's constructor isn't called during another API call effectively making any DI constructor dependency a singleton. There's no way to change the service lifetime to say scoped or transient.
I've read other approaches such as injecting into a Invoke method ala middleware approach but keep getting the RequestDelegate error above.
I fail to see your issue. Transient services support DI when created as long as the DI requirement is also registered. it looks like you did not requester a dbcontext. I have no idea what middleware has to do with your scenario.
Dbcontext is not in my code... so, I fail to see your point :)
let’s assume for sanity that The interface is registered ... it is injected once only for non controller class. The controller class works fine and the controller is fired correctly as singleton or scopes or transient for each api call. the problem is since
the non controller class constructor only fires once it can only be singleton. So, how does non controller classes inject non singleton interfaces.
Your question infers a controller's constructor is somehow different than a class constructor located in a library. Construct injection works the same for a controller class or a custom class that you develop.
I use a separate data access layer in ASP.NET Core and it's very simple and straight forward. It is not clear why you are having problems. Is there anyway you can share source code that reproduces the issue you've described.
Dbcontext is not in my code... so, I fail to see your point :)
let’s assume for sanity that The interface is registered ... it is injected once only for non controller class. The controller class works fine and the controller is fired correctly as singleton or scopes or transient for each api call. the problem is since
the non controller class constructor only fires once it can only be singleton. So, how does non controller classes inject non singleton interfaces.
a non controller class constructor fires every time an instance is created. The pipe line when it creates a controller instance uses the services DI library to get the constructor parameters. If your code creates a class instance then it also need to use
the services api.
Am I able to upload a sample solution? My DAL's constructor does not fire after the initial load. This person has a similar problem and the answer references middleware "Middleware is only instantiated once, so it's a singleton effectively."
the example you link to is using DI on middleware. As all middleware is only created once, all DI is singleton. This does not mean middleware can not use transient DI, it just can not be instantiated in the constructor. you would need to inject a factory
or the services (as a factory) into the middleware constructor, so it could be called in InvokeAsync().
you don't really explain what your issue is. That is, where you are calling the iMyResponse constructor and how you pass it to the MyDal constructor. You also don't explain the use case of DI outside of a controller.
Am I able to upload a sample solution? My DAL's constructor does not fire after the initial load. This person has a similar problem and the answer references middleware "Middleware is only instantiated once, so it's a singleton effectively."
I’ve tried using Invoke method to inject but always get error with requestdelgate
Can’t be resolved
The SO post is using a scoped service in the HTTP pipeline (middleware). Your code does not invoke a service in the HTTP pipeline but tries to populate a
member property. Is there anyway you can clearly explain the design intent and share the actual error message?
public MyDAL(RequestDelegate next)
{
this._next = next;
}
// IMyScopedService is injected into Invoke
public Task Invoke(HttpContext httpContext, IMyResponse iMyResponse)
{
this._iMyResponse = iMyResponse;
return this._next(httpContext);
}
The following is an example that shows how invoke a scoped service in the HTTP Pipeline. A GUID is used to verify the service is scoped.
The service
public class DataAccessMock : IDataAccessMock
{
private readonly ILogger<DataAccessMock> _logger;
private readonly IConfiguration _config;
public Guid Id { get; set; }
public DataAccessMock(ILogger<DataAccessMock> logger, IConfiguration config)
{
_logger = logger;
_config = config;
}
public string GetData()
{
_logger.LogWarning($"Hello from GetData Id: {Id}");
return _config.GetConnectionString("DefaultConnection");
}
}
Custom middleware and extension.
public static class CustomMiddlewareExtensions
{
public static IApplicationBuilder CustomMiddleware(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<CustomMiddleware>();
}
}
public class CustomMiddleware
{
private readonly RequestDelegate _next;
public CustomMiddleware(RequestDelegate next)
{
_next = next;
}
// IMyScopedService is injected into Invoke
public async Task Invoke(HttpContext httpContext, IDataAccessMock svc)
{
svc.Id = Guid.NewGuid();
svc.GetData();
await _next(httpContext);
}
}
Implementation
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.CustomMiddleware();
I’ve tried using Invoke method to inject but always get error with requestdelgate
Can’t be resolved
The SO post is using a scoped service in the HTTP pipeline (middleware). Your code does not invoke a service in the HTTP pipeline but tries to populate a
member property. Is there anyway you can clearly explain the design intent and share the actual error message?
I left out details on usage. No error. The constructor just fires one time so the injected service is always singleton even if it is scoped/transient/etc.
mgebhard
public MyDAL(RequestDelegate next)
{
this._next = next;
}
// IMyScopedService is injected into Invoke
public Task Invoke(HttpContext httpContext, IMyResponse iMyResponse)
{
this._iMyResponse = iMyResponse;
return this._next(httpContext);
}
The following is an example that shows how invoke a scoped service in the HTTP Pipeline. A GUID is used to verify the service is scoped.
I am going to implement this exact code in my solution. I've tried a similar approach but kept getting an "unable to resolve RequestDelegate" error. From what I've read, this is the only way to inject service in a non-controller class which is fine as long
as it fires on each service call and the injected interface is scoped properly.
this is the only way to inject service in a non-controller class which is fine as long as it fires on each service call and the injected interface is scoped properly.
You are mistaken. I provided working examples and I'm not sure what else I can do to help you.
I was referring to your example as being the only way to achieve non singleton. I tried to implement the same way but got the unable to resolve error with request delegate. I will use your example in my solution. I must be doing something silly.
Thank you for the help. I believe the above call to CustomMiddleware should be "UseMiddleware" like below. This helped me find the root of my problem. My DAL class inherits from an interface that is injected into the domain (projects do not link to each
other) which resulted in a the "RequestDelegate" error I was receiving upon load. After the inheritance is removed, the error goes away but my domain layer cannot call the DAL. So, last question (I THINK), how do I use inheritance on a middleware (non-controller)
class?
Unable to resolve service for type 'Microsoft.AspNetCore.Http.RequestDelegate' while attempting to activate
I believe the above call to CustomMiddleware should be "UseMiddleware" like below.
No, I clearly named the extension method CustomMiddleware.
SAgosto
So, last question (I THINK), how do I use inheritance on a middleware (non-controller) class?
Your question makes little sense. Inheritance is an OOP concept that has little to do with middleware. Clearly explain why you are adding a data access library to the HTTP Pipeline? Typically, a data access library is designed as a service then registered
with the DI container. Once register with DI, the data access library can be injected into any class constructor.
Why are you adding data access to the HTTP pipeline? Are you executing a query to validate a security token or user data?
I need to be able to inject dependencies into a non-controller class. This is done via the UseMiddleware and the Task/TaskAsync methods. However, if that class implements an interface the following error occurs:"Unable to resolve service for type 'Microsoft.AspNetCore.Http.RequestDelegate'"
I need to be able to inject dependencies into a non-controller class. This is done via the UseMiddleware and the Task/TaskAsync methods.
You are mistaken. Dependency injection in ASP.NET Core is not dependent on a controller. Any class constructor will work as illustrated above. There is no logical reason to invoke a data access library in middleware unless you need to execute a query
in HTTP pipeline. Typically, the data access layer is invoke within a controller action or a business layer (standard service) depending on how the code is designed.
SAgosto
However, if that class implements an interface the following error occurs:"Unable to resolve service for type 'Microsoft.AspNetCore.Http.RequestDelegate'"
The error means you forgot to register the service. Again, see the examples above.
You are mistaken. Dependency injection in ASP.NET Core is not dependent on a controller. Any class constructor will work as illustrated above. There is no logical reason to invoke a data access library in middleware unless you need to execute a query
in HTTP pipeline. Typically, the data access layer is invoke within a controller action or a business layer (standard service) depending on how the code is designed.
Apologies if I am not clear. DI in .NET Core requires additional work for non-controller class. You cannot use constructor for non-singleton hence the need for Invoke/InvokeAsync.
This framework has 3 layers: controller, domain, and DAL. Each tier uses interfaces to communicate with each other to avoid project-to-project dependencies. This means that domain layer injects an instance of the dal's interface. Since the DAL inherits from
an interface, the "unable to resolve RequestDelegate" occurs. If that interface is removed, than the Task/TaskAsync methods are invoked and the non-singleton dependencies are load as expected.
mgebhard
The error means you forgot to register the service. Again, see the examples above.
Nope. If I remove IMyDAL from public class MyDAL : IMyDAL -> All is good!
Apologies if I am not clear. DI in .NET Core requires additional work for non-controller class. You cannot use constructor for non-singleton hence the need for Invoke/InvokeAsync.
I fail to see your point. I have production applications that take advantage of scoped and transient services.
SAgosto
Nope. If I remove IMyDAL from public class MyDAL : IMyDAL -> All is good!
You are doing something wrong or I'm missing the point. Post sample code that reproduces this issue so we can get on the same page.
Member
1 Points
15 Posts
.NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 25, 2019 02:18 PM|SAgosto|LINK
My .NET Core / MVC application has 3 service/controller, domain, and data access layer ties. Each API call within the service/controller layer works as expected where the iMyResponse is always injected based on registration. The Domain/DAL initialize the 1st API call resulting in a singleton approach and not allow transient or scoped service lifetime. What am I missing? This seems very straight forward.
public MyDAL(IMyResponse iMyResponse) { iMyResponse is only called once so the service lifetime cannot be scoped or transient }
services.AddTransient();
<div> public MyDAL(RequestDelegate next)</div> <div> {</div> <div> this._next = next;</div> <div> }</div> <div> </div> <div> // IMyScopedService is injected into Invoke</div> <div> public Task Invoke(HttpContext httpContext, IMyResponse iMyResponse)</div> <div> {</div> <div> this._iMyResponse = iMyResponse;</div> <div> return this._next(httpContext);</div> <div> }</div>I've tried using a middleware approach but get the following error: "Unable to resolve service for type 'Microsoft.AspNetCore.Http.RequestDelegate'"
All-Star
53554 Points
13305 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 25, 2019 03:46 PM|bruce (sqlwork.com)|LINK
You probably should be injecting a iMyResponse factory not object instance, but you don’t explain the usage well enough to know.
Contributor
3981 Points
3344 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 25, 2019 03:58 PM|DA924|LINK
The DAL is using the DAO and DTO patterns. The DTO travels between the Web API client and service. The DAL is sitting behind the WebAPI service and the service is calling on the DAO objects in the DAL for CRUD.
https://en.wikipedia.org/wiki/Data_transfer_object
https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5
https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp
https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 25, 2019 04:21 PM|SAgosto|LINK
I am trying to understand why the DAL's constructor isn't called during another API call effectively making any DI constructor dependency a singleton. There's no way to change the service lifetime to say scoped or transient.
I've read other approaches such as injecting into a Invoke method ala middleware approach but keep getting the RequestDelegate error above.
Contributor
3981 Points
3344 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 25, 2019 09:00 PM|DA924|LINK
It seems to be overly complicated.
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 26, 2019 03:06 AM|SAgosto|LINK
Agreed but someone must have handled this case.
All-Star
53554 Points
13305 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 26, 2019 03:05 PM|bruce (sqlwork.com)|LINK
I fail to see your issue. Transient services support DI when created as long as the DI requirement is also registered. it looks like you did not requester a dbcontext. I have no idea what middleware has to do with your scenario.
please read the service DI documentation.
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 26, 2019 03:12 PM|SAgosto|LINK
let’s assume for sanity that The interface is registered ... it is injected once only for non controller class. The controller class works fine and the controller is fired correctly as singleton or scopes or transient for each api call. the problem is since the non controller class constructor only fires once it can only be singleton. So, how does non controller classes inject non singleton interfaces.
All-Star
43721 Points
18706 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 26, 2019 03:42 PM|mgebhard|LINK
Your question infers a controller's constructor is somehow different than a class constructor located in a library. Construct injection works the same for a controller class or a custom class that you develop.
I use a separate data access layer in ASP.NET Core and it's very simple and straight forward. It is not clear why you are having problems. Is there anyway you can share source code that reproduces the issue you've described.
All-Star
53554 Points
13305 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 26, 2019 05:38 PM|bruce (sqlwork.com)|LINK
a non controller class constructor fires every time an instance is created. The pipe line when it creates a controller instance uses the services DI library to get the constructor parameters. If your code creates a class instance then it also need to use the services api.
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 26, 2019 07:39 PM|SAgosto|LINK
Am I able to upload a sample solution? My DAL's constructor does not fire after the initial load. This person has a similar problem and the answer references middleware "Middleware is only instantiated once, so it's a singleton effectively."
https://stackoverflow.com/questions/41856278/asp-net-core-di-only-injects-singletons-scoped-and-transient-not-working
All-Star
53554 Points
13305 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 26, 2019 10:12 PM|bruce (sqlwork.com)|LINK
the example you link to is using DI on middleware. As all middleware is only created once, all DI is singleton. This does not mean middleware can not use transient DI, it just can not be instantiated in the constructor. you would need to inject a factory or the services (as a factory) into the middleware constructor, so it could be called in InvokeAsync().
you don't really explain what your issue is. That is, where you are calling the iMyResponse constructor and how you pass it to the MyDal constructor. You also don't explain the use case of DI outside of a controller.
All-Star
43721 Points
18706 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 26, 2019 10:14 PM|mgebhard|LINK
I think you misunderstand the SO post. As far as I can tell the user is trying to add security to the HTTP Pipeline.
The pattern is very simple though.
A library.
Register the service in startup.cs
Inject the service in a controller.
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 26, 2019 11:08 PM|SAgosto|LINK
Can’t be resolved
All-Star
43721 Points
18706 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 27, 2019 11:40 AM|mgebhard|LINK
The SO post is using a scoped service in the HTTP pipeline (middleware). Your code does not invoke a service in the HTTP pipeline but tries to populate a member property. Is there anyway you can clearly explain the design intent and share the actual error message?
public MyDAL(RequestDelegate next) { this._next = next; } // IMyScopedService is injected into Invoke public Task Invoke(HttpContext httpContext, IMyResponse iMyResponse) { this._iMyResponse = iMyResponse; return this._next(httpContext); }
The following is an example that shows how invoke a scoped service in the HTTP Pipeline. A GUID is used to verify the service is scoped.
The service
public class DataAccessMock : IDataAccessMock { private readonly ILogger<DataAccessMock> _logger; private readonly IConfiguration _config; public Guid Id { get; set; } public DataAccessMock(ILogger<DataAccessMock> logger, IConfiguration config) { _logger = logger; _config = config; } public string GetData() { _logger.LogWarning($"Hello from GetData Id: {Id}"); return _config.GetConnectionString("DefaultConnection"); } }
Custom middleware and extension.
Implementation
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 27, 2019 07:05 PM|SAgosto|LINK
I left out details on usage. No error. The constructor just fires one time so the injected service is always singleton even if it is scoped/transient/etc.
I am going to implement this exact code in my solution. I've tried a similar approach but kept getting an "unable to resolve RequestDelegate" error. From what I've read, this is the only way to inject service in a non-controller class which is fine as long as it fires on each service call and the injected interface is scoped properly.
All-Star
43721 Points
18706 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 27, 2019 08:47 PM|mgebhard|LINK
You are mistaken. I provided working examples and I'm not sure what else I can do to help you.
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 27, 2019 09:15 PM|SAgosto|LINK
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 30, 2019 05:29 PM|SAgosto|LINK
Thank you for the help. I believe the above call to CustomMiddleware should be "UseMiddleware" like below. This helped me find the root of my problem. My DAL class inherits from an interface that is injected into the domain (projects do not link to each other) which resulted in a the "RequestDelegate" error I was receiving upon load. After the inheritance is removed, the error goes away but my domain layer cannot call the DAL. So, last question (I THINK), how do I use inheritance on a middleware (non-controller) class?
/// <summary>
/// Use CasePushDAL's middleware
/// </summary>
/// <param name="builder">App Builder</param>
/// <returns>IApplicationBuilder</returns>
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<DAL.MyDAL>();
}
All-Star
43721 Points
18706 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 30, 2019 05:51 PM|mgebhard|LINK
No, I clearly named the extension method CustomMiddleware.
Your question makes little sense. Inheritance is an OOP concept that has little to do with middleware. Clearly explain why you are adding a data access library to the HTTP Pipeline? Typically, a data access library is designed as a service then registered with the DI container. Once register with DI, the data access library can be injected into any class constructor.
Why are you adding data access to the HTTP pipeline? Are you executing a query to validate a security token or user data?
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 30, 2019 06:25 PM|SAgosto|LINK
I need to be able to inject dependencies into a non-controller class. This is done via the UseMiddleware and the Task/TaskAsync methods. However, if that class implements an interface the following error occurs:"Unable to resolve service for type 'Microsoft.AspNetCore.Http.RequestDelegate'"
All-Star
43721 Points
18706 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 30, 2019 06:42 PM|mgebhard|LINK
You are mistaken. Dependency injection in ASP.NET Core is not dependent on a controller. Any class constructor will work as illustrated above. There is no logical reason to invoke a data access library in middleware unless you need to execute a query in HTTP pipeline. Typically, the data access layer is invoke within a controller action or a business layer (standard service) depending on how the code is designed.
The error means you forgot to register the service. Again, see the examples above.
Member
1 Points
15 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 30, 2019 07:36 PM|SAgosto|LINK
Apologies if I am not clear. DI in .NET Core requires additional work for non-controller class. You cannot use constructor for non-singleton hence the need for Invoke/InvokeAsync.
This framework has 3 layers: controller, domain, and DAL. Each tier uses interfaces to communicate with each other to avoid project-to-project dependencies. This means that domain layer injects an instance of the dal's interface. Since the DAL inherits from an interface, the "unable to resolve RequestDelegate" occurs. If that interface is removed, than the Task/TaskAsync methods are invoked and the non-singleton dependencies are load as expected.
Nope. If I remove IMyDAL from public class MyDAL : IMyDAL -> All is good!
All-Star
43721 Points
18706 Posts
Re: .NET Core - Use Dependency Injection In non controller classes such as data access layer
Oct 30, 2019 08:11 PM|mgebhard|LINK
I fail to see your point. I have production applications that take advantage of scoped and transient services.
You are doing something wrong or I'm missing the point. Post sample code that reproduces this issue so we can get on the same page.