Dependency injection with very different requirements - c#

I have a C# ASP.NET MVC app that will need to connect to a third party WCF service but will probably move to a REST API in the future. I can nicely split out the app into various UI elements, View Models, interfaces, and implementations such as IRegister, ILogon, etc. and then potentially have WCF and REST versions of each.
The problem is for DI, I'd want to pass in a connection as part of the constructor of each. The nature of the WCF connection is a large Interface/contract object that then links to all available methods of the third party system. The REST connection needs to pass in an already established authorization token, and then make a series of API calls.
How would I implement the actual connection, would I just use a data type of "object".

I take it that you are trying to inject some sort of connection settings into some kind of repository. Depending on the methods called in the repository you are either calling an "old" WCF API or a "new" REST API. Since the WCF client is probably generated by making a Service Reference. The client itself can be injected.
For the REST API you would need some sort of factory that will retrieve first the security token and then return a self implemented REST client which has the token passed through its constructor. Of course depending on the lifetime of the token you might have to take different approaches to make sure your token remains valid.
The REST client would expose the required methods to make the calls passing the security token along with each request. The HttpClient class allows for default headers to be sent with every subsequent request. Making it very easy.

Create seperate class for Service and implement the interface as well
Example class : - SignInService.cs
Interface : - ISignInService
Then inject your service class via interface in startup.cs
Example -
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ISignInService, SignInService>();
}

Related

Best way to have two versions of a dependency per application part using Unity?

I am using Unity and MVC5 .NET 4.6
I have a data service.
It depends on a repository.
Which in turn depends on a connection.
The connection requires a username/token to make a connection OR a user/application guid to make a connection to a data source.
Both MVC controllers and Web API use the data service, but the data service should not care about how it is being used.
When I used an MVC controller the username and a token is is in the
claim.
When a connected application uses the API it must pass in the
user GUID and application GUI.
When I inject the data service to the controller Unity news up all the dependencies, data service with a repository injected and the repository the connection injected.
The question is what is the best pattern for getting the variables for the user to the connection from the current controller?
You can configure two different containers, one for MVC and one for Web API. Or, if you have a service that needs to be shared between MVC and Web API (e.g. a singleton service), you can create two Child Containers (call container.CreateChildContainer()) of the container you already have and only register the connection in the Child Containers. You can then make a distinction between which connection is used for MVC and for Web API.

How can I mock another web service?

I have code that calls a web service. We'll say a "3rd party" web service. So I can get the wsdl for this service, in fact I've generated a proxy class using this wsdl.
The requirement that I'm trying to meet is this: Create a web service that LOOKS just like the above mentioned one, but does other stuff. So the web service URL will be changed in a config file/database, to allow switching between the two web services.
What I'm not sure about is how I can use that proxy class that I generated, or some other method, so that the namespacing and data contract look exactly the same. I don't know much about this and these are terms that colleagues have tossed out there. I only need to actually implement one of the web service's methods in my version.
Build site with any technology you know of and return responses that match that service.
Note that if you just need to return static enough responses for occasional testing you can use Fiddler as it allows to return arbitrary responses instead of real once.

Execute a SOAP based web services dynamically without generating proxy

In my application, end user can fetch the data from any SOAP based web services and use it in the application. The application provides an option to register the service on fly. The application examine the service, show available operations along with parameter, finally execute the selected operation and use the response, of course everything will be on the fly. There are few steps need to be follow in order to achive that:
Discover the service through WSDL
Examine it and select a method
Build required parameter values
Execute the service
Handle the response
I am able to discover the service on the fly using some WCF classes like DiscoveryClientProtocol, WsdlImporter, ServiceDescription, ServiceContractGenerator, etc. Now, I want to execute them and take the response XML that is available inside SOAP Body.
I am able to execute it by generating the Assembly at runtime using above library and execute a method through reflection. This solution works fine if I have to do everything in single-shot on a box. But it adds complexity when we scale-out. That means, one server generates the proxy, another one use the proxy and consume the services.
Yes, we can keep newly generated assembly somewhere in shared location and use them. But I want to avoid them. We want to keep service definition locally somewhere in DB, execute it without generating assembly and just consume the XML available inside SOAP body.
Appreciate the advice in advance on how to achieve this?
To communicate with WCF services without code generation you use the ChannelFactory< T > where T is the service interface.
Obviously in your case the service interface is not known at compile time so your objective would be to dynamically generate this type, or better yet use a custom ChannelFactory implementation that does not rely on strong typing and lets you call methods in a dynamic or programmatic way.
You can use the WsdlImporter to import the WSDL at runtime and which can give you the ContractDescriptions. From there you might be able to use ContractType as your service interface but I'm not sure. You may need to write your own ChannelFactory...
You can implement ChannelFactory to your abstract generic BaseFactory class which has override CreateDescription method to set Binding and Endpoint for ChannelFactory.ServiceEndpoint. You can pass your configuration interface which has Binding, Endpoint and Credentials to this abstract class. So you can have a dynamic proxy for a wcf service.

Using ServiceStack as an API Facade layer

We currently have one big C# ServiceStack API project for all the services within our system. I want to split this up into smaller API's that all run separately, for ease of deployment and testing. Pretty similar to what's described here by Mike Hadlow.
However, instead of using Nginx I'd like to use ServiceStack as the reverse proxy. This "external" API would handle authentication concerns and then forward any incoming request to the relevant internal API, using an async HTTP REST call.
How would I create this service forwarder, though? Let's say I have an internal API that accepts a /hello call. If I try to create a custom ServiceRunner on the external API host I cannot just intercept ANY call. It still expects certain routes to be present, so calling /hello on the external API fails. Do I need to create dummy /hello route on the external API host in order to be able to intercept them with my own ServiceRunner? Looking at the rest of ServiceStack I'm sure there's a cleaner way.
Bonus points if it can still be combined with Swagger :)
At the time this question was originally asked, there was no simple way of creating a wildcard route off the the root of the service base url. I.e. if the service was hosted at the root, there was no simple way to create a /{*} wildcard route, same if the service was hosted at another point, say /api, there was no simple way to create a /api/{*} wildcard route.
However, support for a Fallback route has recently been added to ServiceStack (see detailed example implementation.) Using a Fallback route, you can proxy all unrecognized requests to the back-end without having to enumerate them in your ServiceStack project. Doesn't provide Swagger support, however.
You can easily convert ServiceStack into a Reverse Proxy with the new Proxy Feature added in v4.5.10.

WCF Data Service - Proxy mid-tier service

The project we are working on is a classic 3 tiered architecture. tier 1 being the database server, tier 2 the application services and tier 3 the presentation tier (a web site).
In the application services tier I have a project that includes an entity framework model and a WCF data services based service that exposes the entities within the model e.g.:
public class DataService : DataService< PortalEntities >
This is a fully fledged OData service that can be queried through the URI e.g.: /dataservice.svc/mytable?$filter=contains(fieldname,’string’). This is great for the guys developing anything using jQuery as all they have to do is define the query. The problem is that this service is a mid-tier so it cannot be seen by the outside world.
The solution that I am trying is to expose another WCF data service on the web site that exposes the entities created by the service reference. If I add a service reference to the mid-tier service it gives me a data context that data context is being used in the new WCF Data service:
public class DataService : DataService< PortalEntities >
I do have to overwrite the CreateDataSource:
protected override PortalEntities CreateDataSource()
{
return new PortalEntities(GetMianModelServiceUri());
}
The new service does act like a proxy and does return the entities exposed (the query .../Services/OData/DataService.svc/tbl_Country works fine).
But when a query is passed to the service e.g.: .../OData/DataService.svc/tbl_Country?$select=Name it throws a not implemented exception.
Any ideas on how to extend the web site service so that it supports the same queries as the mid-tier service?
If you don't need to change the shape or functionality of the data server, you should be able to simply forward the requests and responses, just like a transparent HTTP proxy. The only difference you might need to do is to tweak the service URL. Since the proxy service will have a different base URI than the real service, the payload would contain the real service URIs (in the links and such), which would not work. You can workaround this by using a custom host for your real service and lie to it about its URI. This is done through IDataServiceHost2 interface, you return the "new" URI from the AbsoluteRquestUri and AbsoluteServiceUri properties. Nice sample of an implementation of the interface (although for a different purpose) is here: Link.
If you need to change the shape or functionality, then you really need a true layering.
Layering one WCF Data Service over another is currently rather hard. The LINQ expression trees generated by the "Server" are not always understood by the "Client" LINQ provider. That's what you're running into.
There's a prototype (more like an experiment) of making this work to some extent by rewriting the expression trees. It's part of the OData Provider Toolkit which you can download here http://www.odata.org/developers/odata-sdk#/media/7579/odataprovidertoolkit.zip. (It's in the Experimental folder, AstoriaOverAstoria project).
But please be aware that this is really just an experiment to show what kind of issues are there to be solved and so on. I definitely recommend to NOT use it in any kind of production environment.
I have found it possible to expose a service on the Web Tier that references a service (not data directly) on the App Tier. This only works for queries at the moment. I am not sure what is needed to get it working for updates, deletes etc. Any Ideas anyone? Anyway, here are some instructions and code snippets:
First you create a WCF Data Service on the App Tier bound to your edmx model.
Then create WCF Data Service on the Web Tier not bound to an edmx model (custom).
Create a Service Reference in the Web Tier Service to the App tier service.
Pass the Entities type to the DataService generic declaration (should be angle brackets for VB but I couldn't get them to show:
Public MyWebTierService
Inherits DataService[MyServiceReference.MyAppTierEntities]
Add an override for CreateDataSource() that creates your reference to the App Tier:
Protected Overrides Function CreateDataSource() As MyServiceReference.MyAppTierEntities
Dim ctx = New MyServiceReference.MyAppTierEntities(New Uri("http://yourappservicelocation/AppService.svc/"))
Return ctx
End Function
All you do now is create a reference to the service or bind it to your client app that
supports OData. JSONP support can be added if required.
So, this works fine for Queries but not for updates, probably because the Types are not the same (they may look the same, but are in difference assemblies after all). So, tracking is lost between the Web and App Tiers.
It may be that we have to implement IUpdatable on the Web Tier to solve this. Not sure yet so any input would be useful.
Hope this helps

Categories