My team is building an API which interfaces with another API with many endpoints. Our app is in .net core, so we've been using the connected services wizard for each reference. This means we had to specify the URI's for our endpoints.
Everything is working as expected, but when we move out of dev/qa to staging, all of those references will be wrong, and I will have to manually switch the connected service url's (I think I can do this by simply accessing the ConnectedService.json for each reference and changing extended data: inputs: "[url]" to the different url, but that would mean changing ~20 (so far) references every time we change environments.
My boss says it will become unmanageable as the scope widens. Is there a way to implement dependency injection for service reference uri's so that when the env changes, I can change the reference automatically in code? (I will have the references base url saved in appsettings.json so we can change it without recompiling, because the base url is shared by all of the services, and the wsdl name at the end of it stays the same for each reference across environments.)
The reason I'm asking this as a new question is because, for one, there is limited help on the .net core implementation of service references with the wizard. Most solutions I've found are from 10-15 years ago and it took me a day to realize that those solutions don't apply. An example of a relevant solution is found here: Changing WCF Reference Url .Net Core, however, I don't understand the proposed solution at all.
In the solution, the OP says that adding the code var client = new GetUrlContractClient(new BasicHttpBinding(), new Endpoint("https://someurl/v3/GetUrl-Prod.svc");
solved the problem of updating the uri. My question is, where does this code live, and what is this client object? When I make a call to the API we're referencing, I create a new object asynchronously, there is no reference to some pre existing variable like client
above... Did we already have to implement this somewhere and I'm just not seeing it? And what even is this GetUrlContractClient that is being called? I don't understand where the OP is using this if they set up the reference using the wizard.
[Edit] I should say that I also found that implementing the partial method "ConfigureEndpoint" to extend the auto generated code is the "preferred solution," as seen here load WCF service by environment in .net core project. When I try my best to do this for one of the references, it throws a security exception. If this is the way to do it, then I will devote my time to solving that error. However, this solution involves extending the ConfigureEndpoint for every reference, so I would have to do it upwards of 15 times, so it didn't seem to me that it would be the solution. Maybe this is what the OP for the referenced question was doing, but if so I do not see the connection. They seem to be completely different solutions.
It seems like this would be a relatively straight forward thing to lookup and solve with what we've already implemented, but I have had no luck. Anytime I find something, the answer is vague-ish like above and I don't see how it applies to my situation. How can I change the uri's for my web service references that are set up with the web service reference wizard?
CodePudding user response:
Extending ConfigureEndpoint for each connected service works. The path cannot not include the ?wsdl at the end. The extension code (for one of my files) is below.
public partial class CreateOrderPortTypeClient
{
const string uriSuffix = "(last part of URI without ?wsdl)";
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials)
{
EndpointCreator.SetServiceEndpointAddress(serviceEndpoint, uriSuffix);
}
}
I also added a class EndpointCreator
which handles the base address, like so.
public class EndpointCreator
{
static string uriBase;
public static void GenerateBaseAddress(string uriBase)
{
EndpointCreator.uriBase = uriBase;
}
public static void SetServiceEndpointAddress(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, string uriSuffix)
{
serviceEndpoint.Address =
new System.ServiceModel.EndpointAddress(new System.Uri(uriBase uriSuffix),
new System.ServiceModel.DnsEndpointIdentity(""));
}
}
I assigned the uriBase in startup by accessing the config. While I had to extend each one individually, its actually very manageable because this is a small thing to do when adding a new service through the wizard.