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.