none
Expose Interface for Third Parties to Implement RRS feed

  • Question

  • Hi All,

    I'd like to create an Interface for a WCF service that I would like third parties to implement, and for me to call.

    Basically, I want the users to be able to enter the URL for their service in the settings of my application, and for me to be able to call that service with the specified methods. My end goal, is to be able to call their service whenever certain events happen in my application (such as when data changes), so that their system can be updated in real time.

    Is this possible? If so, how would I go about doing it (i.e. are there any good articles that detail how to achieve this kind of thing)?

    Thanks

    Fergal

    Thursday, March 21, 2013 10:01 PM

Answers

  • On 3/21/2013 7:19 PM, ObsidianPhoenix wrote:

    The point is that I want to define the interface, then hand it off (almost like a wsdl I suppose) for third parties to implement - i.e. I don't want to implement it myself, just define the contract.

    You can make an Interface to be implemented by some class. But the only thing that's going to be implemented is stub-code. But  you are forcing the client to create the code to connect to the WCF service themselves. Why would they want to do that?


    I suppose my point, is that I want to present the interface to the third parties in a manner where I don't actually care how they build it (i.e. what technology/language/etc). From my perspective, all I care about is that they've used my defined interface to write their service, and that I have the URL that points to that service. If they choose to write it in .Net, or Java, etc, is none of my concern.

    The client's responsibility is to consume the WFC Service,  and they can see all of the public operational contracts and use a public method in a contract.


    I know we can use the wsdl to hand off the contract for my own WCF service, so that they are able to implement that in their application in my project, but I want to do it the other way around.

    Have you used Interfaces before? Someone you have given a WCF IService to so they can implement it would really mean nothing to the client. The Interface can be implemented in a class and stub-code representing the Interface is going to be generated,  and they still have to hook it up to the service.
     To me it should be give me the url to your WCF service, I'll consume the WCF Web service and you give me the location where I can download some documentation about the service and how to use it. That's how I have seen all 3rd party Web services WCF or not be implemented used by the clients of the 3rd party Web based solution.
     You might be able to give an Interface to a WCF Restful Web service where URI(s) are being used.

    <http://www.dotnetobject.com/Thread-Consuming-WCF-RESTful-Web-Service>

    Friday, March 22, 2013 2:10 AM
  • Hi ObsidianPhoenix,

    My understanding is that you want to define a standards/contract for users of your application so that they can follow it to implement some services which can be invoked by your application, correct?

    If so, I think you will need to define several things together so as to make up the "inteface" in this context. You might consider go through a "Contract-First" approach when development WCF/XML webservice. Suppose you're the users who will use your app and implement the callback service for you, what you need and how will you implement the service. You will need WSDL document, and you will need xsd (xml schema) files which contains all the type definition of the message or data that will be exchanged through the service. And you might also need to provide a sample implementation (via .NET WCF or ASMX webservice) so that others can use it as a template. Or if the users are all .NET developers, you can even create a Visual Studio project template for them to quickly generate a helloworld service stub :)

    In addition, have you considerred using RESTful service (depend on the requirement of your service)? If REST service is ok here, it would be more convenient for you to define the interface. You just need to specify the HTTP verb (get, post or other...) and a sample request/response format (JSON for XML).


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, March 25, 2013 10:28 AM
    Moderator

All replies

  • On 3/21/2013 6:01 PM, ObsidianPhoenix wrote:

    Hi All,



    I'd like to create an Interface for a WCF service that I would like third parties to implement, and for me to call.

    You have to do the implementation with an Interface of your making, and a class of your making the implements the Interface.  You don't address the WCF Interface and you can't do, which is implemented by the WCF Service.cs. All you are going to be able to address are the public operational contracts presented by the WCF service to the WCF client.
     >

    Basically, I want the users to be able to enter the URL for their service in the settings of my application, and for me to be able to call that service with the specified methods. My end goal, is to be able to call their service whenever certain events happen in my application (such as when data changes), so that their system can be updated in real time.

    A classlib project can consume any amount of services WCF or non WCF services, like a legacy Web service, a WCF Web service or a non Web WCF service.


    Is this possible? If so, how would I go about doing it (i.e. are there any good articles that detail how to achieve this kind of thing)?

    It's called a Servicelayer a classlib project that has a class called the TheService, and the project consumes the WCF Web service.

    The class implements IService1, which points to the same named operational contract method names presented by the WCF service.

    Any project type can set reference to the the Service Layer DLL and use the WCF Web service through the classlib project.

    using System.Collections.Generic;
    using BLL.DTO;

    namespace Services.IServices
    {
        public interface IService1
        {
            List<DTOAuthor> GetAuthors();
            List<DTOAuthor> GetAuthorsWhere();
            List<DTOAuthor> SaveAuthors(List<DTOAuthor> authors);
            DTOPayroll GetPayRollByAuthorID(int id);
            void UpdatePayRollSalary(DTOPayroll pr);
            DTOPayroll AddPayRoll(DTOPayroll pr);
            void DeletePayRoll(DTOPayroll pr);
            DTOArticle GetArticleTop1();
            DTOArticle GetArticle(int id);
            List<DTOArticle> GetArticles();
            List<DTOArticle> SaveArticles(List<DTOArticle> articles);
            void DeleteArticle(DTOArticle srticle);
        }
    }
      using System;
    using System.Collections.Generic;
    using System.Linq;
    using BLL.DTO;
    using Services.IServices;
     namespace Services
    {
        public class TheService1 : IService1
        {
            private static readonly TheService1 mInstance = null;
             public static TheService1 Instance
            {
                get { return mInstance; }
            }
             static TheService1()
            {
                mInstance = new TheService1();
            }
             public List<DTOAuthor> GetAuthors()
            {
                var client = new WCFServiceReference.Service1Client();
                var authors = new List<DTOAuthor>();
                 try
                {
                    var dtoauthors = client.GetAuthors();
                    client.Close();
                     authors.AddRange(dtoauthors.Select(dtoauthor => new DTOAuthor()
                    {
                        AuthorID = dtoauthor.AuthorID,
                        FirstName = dtoauthor.FirstName,
                        LastName = dtoauthor.LastName,
                        IsUpdate = dtoauthor.IsUpdate
                    }).ToList());
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
                 return authors;
            }
             public List<DTOAuthor> GetAuthorsWhere()
            {
                var client = new WCFServiceReference.Service1Client();
                var authors = new List<DTOAuthor>();
                 try
                {
                    var dtoauthors = client.GetAuthorsWhere();
                    client.Close();
                     authors.AddRange(dtoauthors.Select(dtoauthor => new DTOAuthor
                    {
                        AuthorID = dtoauthor.AuthorID,
                        FirstName = dtoauthor.FirstName,
                        LastName = dtoauthor.LastName,
                        IsUpdate = dtoauthor.IsUpdate
                    }).ToList());
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
                 return authors;
            }
             public List<DTOAuthor> SaveAuthors(List<DTOAuthor> auths)
            {
                var client = new WCFServiceReference.Service1Client();
                var authors = new List<DTOAuthor>();
                 try
                {
                    var dtoauthors = client.SaveAuthors(auths.ToArray());
                    client.Close();
                     authors.AddRange(dtoauthors.Select(dtoauthor => new DTOAuthor
                    {
                        AuthorID = dtoauthor.AuthorID,
                        FirstName = dtoauthor.FirstName,
                        LastName = dtoauthor.LastName,
                        IsUpdate = dtoauthor.IsUpdate
                    }).ToList());
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
                 return authors;
            }
             public DTOPayroll GetPayRollByAuthorID(int id)
            {
                var client = new WCFServiceReference.Service1Client();
                var dtopayroll = new DTOPayroll();
                 try
                {
                    dtopayroll = client.GetPayRollByAuthorID(id);
                    client.Close();
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
                 return dtopayroll;
            }
             public void UpdatePayRollSalary(DTOPayroll pr)
            {
                var client = new WCFServiceReference.Service1Client();
                 try
                {
                    client.UpdatePayRollSalary(pr);
                    client.Close();
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
            }
             public DTOPayroll AddPayRoll(DTOPayroll pr)
            {
                var client = new WCFServiceReference.Service1Client();
                var dto = new DTOPayroll();
                 try
                {
                    dto = client.AddPayRoll(pr);
                    client.Close();
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
                 return dto;
            }
             public void DeletePayRoll(DTOPayroll pr)
            {
                var client = new WCFServiceReference.Service1Client();
                 try
                {
                    client.DeletePayRoll(pr);
                    client.Close();
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
            }
             public DTOArticle GetArticleTop1()
            {
                var client = new WCFServiceReference.Service1Client();
                var dto = new DTOArticle();
                 try
                {
                    dto = client.GetArticleTop1();
                    client.Close();
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
                 return dto;
            }
             public DTOArticle GetArticle(int id)
            {
                var client = new WCFServiceReference.Service1Client();
                var dto = new DTOArticle();
                 try
                {
                    dto = client.GetArticle(id);
                    client.Close();
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
                 return dto;
            }
             public List<DTOArticle> GetArticles()
            {
                var client = new WCFServiceReference.Service1Client();
                var articles = new List<DTOArticle>();
                 try
                {
                    var dtos = client.GetArticles();
                    client.Close();
                     articles.AddRange(dtos.Select(dto => new DTOArticle
                    {
                        ArticleID = dto.ArticleID,
                        AuthorID = dto.AuthorID,
                        Title = dto.Title,
                        Body = dto.Body
                    }));
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
                 return articles;
            }
             public List<DTOArticle> SaveArticles(List<DTOArticle> artcs)
            {
                var client = new WCFServiceReference.Service1Client();
                var articles = new List<DTOArticle>();
                 try
                {
                    var dtoarticles = client.SaveArticles(artcs.ToArray());
                    client.Close();
                     articles.AddRange(dtoarticles.Select(dtoarticle => new DTOArticle()
                    {
                        ArticleID = dtoarticle.ArticleID,
                        AuthorID = dtoarticle.AuthorID,
                        Title = dtoarticle.Title,
                        Body = dtoarticle.Body,
                        IsUpdate = dtoarticle.IsUpdate
                    }).ToList());
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
               return articles;
            }
             public void DeleteArticle(DTOArticle article)
            {
                var client = new WCFServiceReference.Service1Client();
                 try
                {
                    client.DeleteArticle(article);
                    client.Close();
                }
                catch (Exception ex)
                {
                    client.Abort();
                }
            }
        }
    }

    Thursday, March 21, 2013 11:12 PM
  • The point is that I want to define the interface, then hand it off (almost like a wsdl I suppose) for third parties to implement - i.e. I don't want to implement it myself, just define the contract.

    I suppose my point, is that I want to present the interface to the third parties in a manner where I don't actually care how they build it (i.e. what technology/language/etc). From my perspective, all I care about is that they've used my defined interface to write their service, and that I have the URL that points to that service. If they choose to write it in .Net, or Java, etc, is none of my concern.

    I know we can use the wsdl to hand off the contract for my own WCF service, so that they are able to implement that in their application in my project, but I want to do it the other way around.

    Thursday, March 21, 2013 11:19 PM
  • On 3/21/2013 7:19 PM, ObsidianPhoenix wrote:

    The point is that I want to define the interface, then hand it off (almost like a wsdl I suppose) for third parties to implement - i.e. I don't want to implement it myself, just define the contract.

    You can make an Interface to be implemented by some class. But the only thing that's going to be implemented is stub-code. But  you are forcing the client to create the code to connect to the WCF service themselves. Why would they want to do that?


    I suppose my point, is that I want to present the interface to the third parties in a manner where I don't actually care how they build it (i.e. what technology/language/etc). From my perspective, all I care about is that they've used my defined interface to write their service, and that I have the URL that points to that service. If they choose to write it in .Net, or Java, etc, is none of my concern.

    The client's responsibility is to consume the WFC Service,  and they can see all of the public operational contracts and use a public method in a contract.


    I know we can use the wsdl to hand off the contract for my own WCF service, so that they are able to implement that in their application in my project, but I want to do it the other way around.

    Have you used Interfaces before? Someone you have given a WCF IService to so they can implement it would really mean nothing to the client. The Interface can be implemented in a class and stub-code representing the Interface is going to be generated,  and they still have to hook it up to the service.
     To me it should be give me the url to your WCF service, I'll consume the WCF Web service and you give me the location where I can download some documentation about the service and how to use it. That's how I have seen all 3rd party Web services WCF or not be implemented used by the clients of the 3rd party Web based solution.
     You might be able to give an Interface to a WCF Restful Web service where URI(s) are being used.

    <http://www.dotnetobject.com/Thread-Consuming-WCF-RESTful-Web-Service>

    Friday, March 22, 2013 2:10 AM
  • Yeah, I've used Interfaces before, specifically in regard to using them in creating WCF services. I'm well aware of how to use them normally - I already have a WCF API that I allow my customers to consume.

    Clearly, you aren't getting what I want to do. I don't want to write a WCF service for my customers to consume (I already have that). I want to define a contract for a WCF service that my customers write, and I consume.

    Perhaps if I use a specific example, you might understand what I'm trying to do:

    Imagine I have a stock ticker application, I've created a WCF service, so that my customers can query my application from their system, and pull in stock information. What I want to do, is give my customers a mechanism that allows me to push changes to them - i.e. they don't query my application, instead a call a WCF service created by them, and send them the data (pretty much event subscription I suppose).

    My initial thoughts on this, were to have them create a WCF service, that they can then enter the URL into my application. But, Given that I have hundreds of customers, this isn't something I define at design time, rather something I hook up to at runtime (based on the URL they entered into my application). In order to achieve this, I need to know about their interface, and I need it to be consistent across all my customers.

    Therefore I want to define the Interface to be used on their service, and have them implement their own service using that Interface. I can then (at runtime) load their URL from my database, and consume their service, pushing the new data out to their application.

    If there is a better way to enable a third party app to subscribe to events through a WCF service, by all means, tell me what that is - that's the whole point of this thread!


    Friday, March 22, 2013 8:21 AM
  • Hi ObsidianPhoenix,

    My understanding is that you want to define a standards/contract for users of your application so that they can follow it to implement some services which can be invoked by your application, correct?

    If so, I think you will need to define several things together so as to make up the "inteface" in this context. You might consider go through a "Contract-First" approach when development WCF/XML webservice. Suppose you're the users who will use your app and implement the callback service for you, what you need and how will you implement the service. You will need WSDL document, and you will need xsd (xml schema) files which contains all the type definition of the message or data that will be exchanged through the service. And you might also need to provide a sample implementation (via .NET WCF or ASMX webservice) so that others can use it as a template. Or if the users are all .NET developers, you can even create a Visual Studio project template for them to quickly generate a helloworld service stub :)

    In addition, have you considerred using RESTful service (depend on the requirement of your service)? If REST service is ok here, it would be more convenient for you to define the interface. You just need to specify the HTTP verb (get, post or other...) and a sample request/response format (JSON for XML).


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, March 25, 2013 10:28 AM
    Moderator
  • Hi Steven,

    Yeah thats right. In discussion here, we came to a similar conclusion - that we'd need to either create an Interface in code, and hand that to the developers who wanted it, or write a document that detailed the methods and objects that they would need to implement.

    Thanks

    Fergal

    Monday, March 25, 2013 10:35 AM