I am working on a WCF application that supports 4 different applications.
lets call those 4 application: App1, App2, App3, and App4.
this WCF Application has 4 services. one for each application. 4 services are very similar, thats why I want to combine them together into 1 wcf application. Here’s the problem, if I need to change the service for App1, I need to redeploy the entire application. even tho, services for App2, App3, and App4 have no changes. I try to avoid that, but I dont want to create 4 different WCF applications because they are very similar, if there’s a change, I probably have to change it 4 times and redeploy 4 times.
I am thinking about using WCF and MEF. I just want to know what other options out there I can explore.
2
One solution is to create WCF interfaces that support extensibility. That is, instead of simply calling a method with a fixed set of parameters, consider calling a method that takes as a parameter, an identifier (which could be an integer) for the method to be called internally. The parameters for the secondary method are packaged as an array of class instances passed as a single parameter to the WCF method.
You would need more information to know for certain what to do here.
My natural inclination would be towards using WCF web methods that takes an identifier parameter. Your web method would have any number of parameters you need based on your requirements (though my preference in this situation would be to provide logic-related parameters as an array containing key/value pairs and all identifier parameters are separate arguments) with one parameter being a version number or app ID.
Your WCF web method’s internal code would act as a router, routing the retrieved values to the correct internal method to process your results based on the target application or version number.
For example, it may turn out that app1, app2, and app3 all use the same version of a hypothetical method DoSomething()
whereas app4 has some additional logical requirement. They can all share the same operation contract and web service, while actually being handled differently under the hood.. The good thing about this approach is that if app5, 6, and 7 emerge in the future you do not need to break your existing operation contracts.
Consider the following:
[ServiceContract]
public interface IApplicationService
{
[OperationContract]
[WebGet(UriTemplate = "/DoSomething?appId={appId}&parms={parms}")]
ResponseObj DoSomething(string appId, string[] parms);
}
public class ApplicationService: IApplicationService {
public ResponseObj DoSomething(string appId, string[] parms)
{
ResponseObj retVal;
switch(appId)
{
case "app1":
case "app2":
case "app3":
retVal = DoSomething(parms);
break;
case "app4":
retVal = DoSomethingElse(parms);
break;
default:
// Handle case
break;
}
return retVal;
}
private ResponseObj DoSomething(string[] parms) { /**logic!**/ }
private ResponseObj DoSomethingElse(string[] parms) { /**logic!**/ }
}
[DataContract]
public class ResponseObj { /**data members**/ }
With something like this your operation contract is never changing. If you change something for the logic in App4, for example, it does not affect 1, 2, or 3. However, your API documentation would need to be clear on the format of your expected array and your private methods would have to validate the retrieved data.
Depending on how things are configured you can do things in other ways. For example, if your web service has a login() method that returns a session, you could tie the version to the session. Now your routing is based on the session state you’re tracking on the server, and you can easily abstract it away in framework code without needing to clutter up your business logic methods.
Personally I have not used MEF with WCF, only MVC4, so I can’t comment on how well it would suit your use case here. The solution I’ve provided does not rely on MEF but is somewhat expensive to maintain over time as you start scaling out to more apps using a shared service. I’ve built something similar for a former employer elsewhere, though it was an abstraction to a control database that provided configuration data for different registered apps via appId.