Introduce dependency injection of services from a custom parameter attribute in Service implementation
See original GitHub issueIntroduce a parameter attribute allowing to inject services from DI directly in Service implementation similar to ASP.NET Core [FromServices]
attribute.
https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.fromservicesattribute?view=aspnetcore-5.0
[ServiceContract]
public interface IService
{
[OperationContract]
Task<Customer> GetCustomerAsync(int customerId, [Injected]DbContext dbContext);
}
This would mean the customer ID comes in as part of the service call, and CoreWCF will fetch from the InstanceContext scoped ServiceProvider the dbContext and add it as a parameter. What are your thoughts?
_Originally posted by @mconnew in https://github.com/CoreWCF/CoreWCF/issues/473#issuecomment-949130495_
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (2 by maintainers)
Top Results From Across the Web
Injecting services into ValidationAttributes in ASP.NET Core
In my first attempt to inject a service I thought I would have to take a similar approach to the ServiceFilter and TypeFilter...
Read more >Dependency injection in ASP.NET Core
ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) ...
Read more >Dependency Injection in ASP.NET Core Attributes
The idea is to use service location, in the constructor to retrieve the required services and set them to class level variables, ...
Read more >c# - Dependency Injection in attributes
extract all logic from the attribute into a custom service that contains all dependencies. Register that service in your container. let the ...
Read more >.NET Dependency Injection With Constructor Parameters
In this article, we'll look at different ways to use dependency injection with constructor parameters in .NET Core.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I was thinking of having the option in the service contract. It wouldn’t show up in the WSDL. We already have the concept of the service contract not being identical between the client and server. Here’s 3 different contracts which produce the exact same on the wire SOAP message:
So there is precedence for having a mismatch in the contracts between the client and the server. I also understand the contract reuse issue. I have some other ideas which I’m not saying are better or preferred, just adding ideas to the conversation.
We could create a helper method to create a ServiceEndpoint for the client to use. One of the constructors of ChannelFactory takes a ServiceEndpoint. We would then need some mechanism to have the client ignore the extra parameters on the call, so that would probably involve a custom IClientMessageFormatter. This option is still a little messy because the client code would need to ignore the extra stuff on the contract and pass null/default in the call. Ideally the client shouldn’t be aware of server side injection dependencies so I’m not a big fan of this idea.
We could create a source generator which scans for any ServiceContract interfaces and checks if they have any
[FromServices]
attributes. If they do, generate a copy of the contract with either a modified name or in a different namespace without the extra parameters. This way you can still write your interface once, so no copy/paste maintenance problems, and have a clean client side contract. It does pull in a client side dependency on the[FromServices]
attribute, but now that asp.net core is a part of .NET, I don’t think that’s as big an issue today as it was a few years ago.We could keep it out of the contract completely. There’s a good argument for this because the contract should be about what’s sent over the wire. This hasn’t been cleanly implemented even today with the ability to apply an attribute which derives from IContractBehavior to the contract itself, or the fact that the .NET sync/async method shape is built in to the contract. We would ideally like to have compile time errors if the interface doesn’t match the implementation. This way if you make contract changes, you will get a compile error if you don’t also make those changes to the implementation. One way to achieve this is with a source generator which generates contract methods based on the implementation methods and not the interface (which would still be used to find candidate methods as not all methods are service implementation methods). This is my favorite idea so far, and wouldn’t need any runtime support in CoreWCF. We would need a source analyzer which enforces needing to make you implementation class partial, but that’s all the changes you would need other than adding the methods. You would write code like this:
What the source analyzer would do is find all ServiceContract interfaces, look for any classes which implement them, then check each method to see if the use
[FromService]
in their method signature, and if they do, require the class to be partial. If it isn’t, that becomes a compilation error. What the source generator would do is emit the following code:The advantage of doing this with a source analyzer/source generator is there’s no runtime changes needed. There are a LOT of places in the code that we would need to touch to implement it in the CoreWCF runtime packages, whereas this is a lot simpler.
Yes, they should be distributed in the CoreWCF.Primitives package. As it’s a build time tool, it won’t increase the application footprint at runtime. It will need to be a separate project which is referenced by the Primitives build but won’t produce its own package.