none
Best practice for separating intranet and web WCF operations. RRS feed

  • Question

  • Hello,

    I am working on designing and building a database application, this application will be setup as a service application.

    I use WCF on my server to host the different services, the final solution will have a WPF client wich will be used on the intranet and a web-application for remote access via a laptop/mobile/tablet. For the database I will use SQL Server.

    The requirements are that the web-application will have a subset of the functionality thats available in the WPF application. I did some research about how to set this up. I came up with the following solution.

    Solution:

    I will use HTTPS binding for the web-application and net.tcp for my intranet application.  To be able to reuse my code I created two different services classes with there own interface for every database table. Then I have one base service class. These classes are linked together as follows, as an example I use the Category table:

    public abstract class ManagerBase<TDto, TEntity> : IService<TDto>
        where TEntity : class, new()
        where TDto : class //IDtoWithKey
    {
    }
    
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
                    ConcurrencyMode = ConcurrencyMode.Multiple)]
    [Export(typeof(ICategoriesService))]
    [Export(typeof(CategoriesManager))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class CategoriesManager : ManagerBase<CategoriesDto, Categories>, ICategoriesService
    {
        #region Fields
            
        public readonly ICategoriesEngine _engine;
            
        #endregion
            
        #region Constructor
            
        [ImportingConstructor]
        public CategoriesManager(
            ICategoriesRepository repository,
            ICategoriesAssembler assembler,
            ICategoriesEngine engine) : base(repository, assembler)
        {
            _engine = engine;
        }
            
        #endregion
    }
    
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
                ConcurrencyMode = ConcurrencyMode.Multiple)]
    [Export(typeof(ICategoriesServiceInternal))]
    [Export(typeof(CategoriesManagerInternal))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class CategoriesManagerInternal : CategoriesManager, ICategoriesServiceInternal
    {
        #region Constructor
    
        [ImportingConstructor]
        public CategoriesManagerInternal(
            ICategoriesRepository repository,
            ICategoriesAssembler assembler,
            ICategoriesEngine engine)
            : base(repository, assembler, engine)
        {
        }
        #endregion
    }


    The CategoriesManager will contain all functionlaity thats common to both the WPF and web-application. The CategoriesManagerInternal class will contain the additional functionality thats only available to the WPF application on the intranet. My bindings are as follows:

    <!-- Binding for the web-application -->
    <service behaviorConfiguration="MetadataBehavior" name="Demo.Northwind.Business.Managers.CategoriesManager">
      <endpoint address="http://localhost:8000/CategoriesService" binding="wsHttpBinding" bindingConfiguration="HttpSecurityBinding"
        contract="Demo.Northwind.Business.Contracts.Services.ICategoriesService" />
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
    
    
    <!-- Binding for the WPF application -->
    <service behaviorConfiguration="ServiceBehavior" name="Demo.Northwind.Business.Managers.InternalManagers.CategoriesManagerInternal">
      <endpoint address="net.tcp://localhost:8001/CategoriesServiceInternal"
        binding="netTcpBinding" bindingConfiguration="" contract="Demo.Northwind.Business.Contracts.InternalServices.ICategoriesServiceInternal" />
      <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />        
    </service>

    I would like to have some feedback on this solution, especially if this is a good practice to separate the functionality thats available through different interfaces (WPF and web-application).

    Any feedback would be greatly appreciated.

    Regards,

    Marcel


    • Edited by marcel222 Sunday, October 19, 2014 11:37 AM
    Sunday, October 19, 2014 11:36 AM

Answers

  • The important thing is what metohods you expose from your WCF service(s). How these methods are implemented on the server side is not important at all as far as the clients are concerned.

    You could for example expose two different contracts, one public and one internal. The internal service contract may extend the public one:

    [ServiceContract]
    public interface IMyPublicService
    {
    [OperationContract]
    int DoSomething();
    }
    
    [ServiceContract]
    public interface MyInternalService : IMyPublicService
    {
    [OperationContract]
    int DoSomethingElse();
    }
    

    The actual implementation of the internal service may also extend (the class may inherit from) the implementation of the public service. You should of course keep all code that are common to both services in the same class.

    Please remember to mark helpful posts as answer and/or helpful.

    • Marked as answer by marcel222 Tuesday, October 21, 2014 9:02 AM
    Sunday, October 19, 2014 3:49 PM