Duplicate class definitions

Discussion in 'ASP .Net Web Services' started by Jeff Johnson, Jan 12, 2007.

  1. Jeff Johnson

    Jeff Johnson Guest

    Disclaimer: I am extremely new to Web services and may very well be doing
    the wrong thing!

    Background: I have a Web service and a Windows Forms client app (VS 2005).
    The Web service exposes a method to accept a ScheduleEntry object, which is
    a class I have written. I felt doing this would be cleaner than passing 7 or
    8 parameters, but I've run into some problems.

    First, I learned that declaring classes in Web services isn't such a great
    idea because the proxy class you get in your client app when you make a Web
    reference only has properties and not methods.

    So I decided that I'd move my class definition to a separate assembly that
    I'd then reference in both the Web service and my app. This sort of works,
    but now I'm getting a separate definition of the class through the Web
    service. This is hard to explain so I'll give an example.

    ---------------
    1. Assembly which contains my class (we'll call it "Scheduling.dll.")

    namespace Main.Name.Space
    {
    public class ScheduleEntry
    {
    // Stuff
    }
    }
    ---------------
    ---------------
    2. Web service

    [WebService(Namespace = http://www.mycompany.com/schedulerservice)]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class SchedulerService : System.Web.Services.WebService
    {
    [WebMethod]
    public int AddScheduleEntry(ScheduleEntry schedule)
    {
    // Stuff
    }
    }
    ---------------
    ---------------
    3. Client app

    This app contains a Web reference which I named "Scheduler" and a regular
    reference to Scheduling.dll. It uses the same namespace as Scheduling.dll
    (i.e., Main.Name.Space). I can see that this namespace contains a class
    known as Main.Name.Space.ScheduleEntry. However, when I create an instance
    of Scheduler.ScheduleService and look at the signature of the
    AddScheduleEntry() method, the parameter is identified as
    Main.Name.Space.Scheduler.ScheduleEntry and I can't pass a
    Main.Name.Space.ScheduleEntry object because the compiler complains that it
    can't cast between those types.

    Is there any kind of decoration I need to do in the Web service so that when
    the WSDL is interrogated and the proxy built in my client the ScheduleEntry
    class comes out with the proper namespace?
    Jeff Johnson, Jan 12, 2007
    #1
    1. Advertising

  2. Jeff Johnson

    RYoung Guest

    I think the way services are developed in WCF might help gain some insight
    into this:

    [DataContract]
    class ScheduleEntry
    {
    public string EntryTitle;
    public DateTime Timestamp;
    }

    [ServiceContract]
    class Scheduler
    {
    [OperationContract]
    public void AddEntry(ScheduleEntry entry)
    {
    }
    }

    The point is that the data (ScheduleEntry) is separate from the
    operations/behaviors/methods that act on that data (Scheduler).

    Your web service is the "point of contact" to communicate with when your
    client app wants operations performed on some ScheduleEntry data. So, other
    than any local processing, your client doesn't need a ScheduleEntry object
    that has behavior, because the service is the behavior.

    That being said, there's no need to reference the Scheduler.dll in your
    client application.

    Your 100% correct in wrapping a group of parameters into a single object
    (ScheduleEntry) and even factoring that and other similiar objects into a
    separate assembly.

    Your service references that assembly, because that contains the information
    it exchanges and accepts.

    In essence, your service says "give me a schedule ID, and I'll send you back
    a ScheduleEntry for that ID", and "give me some ScheduleEntry data, and I'll
    insert it, update it".

    Does that make any sense? What I want to get at here, is I think your
    approach is incorrect in as far as the client app referencing an assembly in
    order to use the behaviors of objects in that assembly and where those
    objects are types being used in the service.

    For instance:

    MyMath.dll

    class Math
    {
    public int X, Y;
    public void Add(){ return X + Y; }
    }

    Service.dll
    [WebService]
    public MyMath.Math GetMath()
    {
    return new MyMath.Math();
    }

    You know what the client will get, a Math object with X and Y fields. If you
    wanted to get a Math object hat had behavior, you'd have to do .NET Remoting
    and have Math derive from MarshalByRefObject, and then your still not
    getting a Math object that can Add() locally. When Add() is called on that
    remoted object, the call will go across the network to the instance of Math
    that the remoting server created and is keeping alive for you.

    The following would more accurately represent a "math" service:

    DataTypes.dll
    class Numbers
    {
    public int X, Y;
    }

    BusinessComponent.dll
    class Math
    {
    public int Add(Numbers numbers){ return numbers.X + numbers.Y; }
    }

    MathService.dll
    class MathService
    {
    public int Add(Numbers numbers)
    {
    return new Math().Add(numbers);
    }
    }

    The MathService is a wrapper around existing functionality so that the
    functionality can be reachable over network protocols.

    Well, I won't go on, but will point out some things that may help:
    http://www.thinktecture.com/Resources/Software/WSContractFirst/default.html
    - scroll down to the "walkthrough" link. It may also address sharing data
    definitions among projects (which is different that sharing objects with
    behavior).

    I highly suggest downloading that tool, going through the walkthrough a
    couple times, then try applying it to your project. I'm almost 100% certain
    it will change the way you think about services, for the better.

    Ron

    "Jeff Johnson" <> wrote in message
    news:...
    > Disclaimer: I am extremely new to Web services and may very well be doing
    > the wrong thing!
    >
    > Background: I have a Web service and a Windows Forms client app (VS 2005).
    > The Web service exposes a method to accept a ScheduleEntry object, which
    > is a class I have written. I felt doing this would be cleaner than passing
    > 7 or 8 parameters, but I've run into some problems.
    >
    > First, I learned that declaring classes in Web services isn't such a great
    > idea because the proxy class you get in your client app when you make a
    > Web reference only has properties and not methods.
    >
    > So I decided that I'd move my class definition to a separate assembly that
    > I'd then reference in both the Web service and my app. This sort of works,
    > but now I'm getting a separate definition of the class through the Web
    > service. This is hard to explain so I'll give an example.
    >
    > ---------------
    > 1. Assembly which contains my class (we'll call it "Scheduling.dll.")
    >
    > namespace Main.Name.Space
    > {
    > public class ScheduleEntry
    > {
    > // Stuff
    > }
    > }
    > ---------------
    > ---------------
    > 2. Web service
    >
    > [WebService(Namespace = http://www.mycompany.com/schedulerservice)]
    > [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    > public class SchedulerService : System.Web.Services.WebService
    > {
    > [WebMethod]
    > public int AddScheduleEntry(ScheduleEntry schedule)
    > {
    > // Stuff
    > }
    > }
    > ---------------
    > ---------------
    > 3. Client app
    >
    > This app contains a Web reference which I named "Scheduler" and a regular
    > reference to Scheduling.dll. It uses the same namespace as Scheduling.dll
    > (i.e., Main.Name.Space). I can see that this namespace contains a class
    > known as Main.Name.Space.ScheduleEntry. However, when I create an instance
    > of Scheduler.ScheduleService and look at the signature of the
    > AddScheduleEntry() method, the parameter is identified as
    > Main.Name.Space.Scheduler.ScheduleEntry and I can't pass a
    > Main.Name.Space.ScheduleEntry object because the compiler complains that
    > it can't cast between those types.
    >
    > Is there any kind of decoration I need to do in the Web service so that
    > when the WSDL is interrogated and the proxy built in my client the
    > ScheduleEntry class comes out with the proper namespace?
    >
    RYoung, Jan 13, 2007
    #2
    1. Advertising

  3. Well the *correct* way to do this is to extend the proxy generator behaviour
    to recognize your types when the proxy code is generated.

    This is not as straightforward as it could be and the easier way to do this
    would be to edit the proxt class code after generation and manually point
    the business object to yours. However, keep in mind that this code will get
    overwritten everytime the proxy generator is invoked.

    The correct way to do it would be:

    1. Create a type that inherits from SchemaImporterExtension
    2. Override the ImportSchemaType method
    3. Write code to check the name and namespace of the type described in the
    WSDL document and replace with your own type and return the generated code.
    4. Give your type a strong name and put it in the GAC (alternatively put it
    in the bin folder)
    5. Register the extension to the proxy generator in the machine.config
    6. Use Add Web Reference or wsdl.exe to generate the proxy.

    HTH.

    --
    With Regards
    Shailen Sukul
    ..Net Architect
    (MCPD: Ent Apps, MCSD.Net MCSD MCAD)
    Ashlen Consulting Services
    http://www.ashlen.net.au
    "Jeff Johnson" <> wrote in message
    news:...
    > Disclaimer: I am extremely new to Web services and may very well be doing
    > the wrong thing!
    >
    > Background: I have a Web service and a Windows Forms client app (VS 2005).
    > The Web service exposes a method to accept a ScheduleEntry object, which
    > is a class I have written. I felt doing this would be cleaner than passing
    > 7 or 8 parameters, but I've run into some problems.
    >
    > First, I learned that declaring classes in Web services isn't such a great
    > idea because the proxy class you get in your client app when you make a
    > Web reference only has properties and not methods.
    >
    > So I decided that I'd move my class definition to a separate assembly that
    > I'd then reference in both the Web service and my app. This sort of works,
    > but now I'm getting a separate definition of the class through the Web
    > service. This is hard to explain so I'll give an example.
    >
    > ---------------
    > 1. Assembly which contains my class (we'll call it "Scheduling.dll.")
    >
    > namespace Main.Name.Space
    > {
    > public class ScheduleEntry
    > {
    > // Stuff
    > }
    > }
    > ---------------
    > ---------------
    > 2. Web service
    >
    > [WebService(Namespace = http://www.mycompany.com/schedulerservice)]
    > [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    > public class SchedulerService : System.Web.Services.WebService
    > {
    > [WebMethod]
    > public int AddScheduleEntry(ScheduleEntry schedule)
    > {
    > // Stuff
    > }
    > }
    > ---------------
    > ---------------
    > 3. Client app
    >
    > This app contains a Web reference which I named "Scheduler" and a regular
    > reference to Scheduling.dll. It uses the same namespace as Scheduling.dll
    > (i.e., Main.Name.Space). I can see that this namespace contains a class
    > known as Main.Name.Space.ScheduleEntry. However, when I create an instance
    > of Scheduler.ScheduleService and look at the signature of the
    > AddScheduleEntry() method, the parameter is identified as
    > Main.Name.Space.Scheduler.ScheduleEntry and I can't pass a
    > Main.Name.Space.ScheduleEntry object because the compiler complains that
    > it can't cast between those types.
    >
    > Is there any kind of decoration I need to do in the Web service so that
    > when the WSDL is interrogated and the proxy built in my client the
    > ScheduleEntry class comes out with the proper namespace?
    >
    Shailen Sukul, Jan 15, 2007
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roedy Green
    Replies:
    4
    Views:
    447
  2. E11
    Replies:
    1
    Views:
    4,742
    Thomas Weidenfeller
    Oct 12, 2005
  3. mathieu
    Replies:
    4
    Views:
    389
    mathieu
    Dec 18, 2007
  4. johkar
    Replies:
    0
    Views:
    1,874
    johkar
    Dec 16, 2009
  5. Rainer Weikusat
    Replies:
    1
    Views:
    213
    Rainer Weikusat
    Mar 8, 2013
Loading...

Share This Page