locked
To Proxy or Not To Proxy... RRS feed

  • Question

  • First the situation:

     

    I have service1 with a service1state object, which is a complicated object, and along with it's data members, there are also several member functions.

     

    Lots of services partner with service1, and then I would like to use the service1state member functions. If I've only referenced the proxy.dll, I don't have access to those member functions. It would be inefficient and tedious to copy those functions into each of the services that needed them.

     

    So my question is this, if services are on the same node, is it really that bad of an idea to reference the assembly dll instead of the proxy? Or maybe there is another way to access the member functions through the proxy?

     

    -Don

    Thursday, April 19, 2007 8:30 PM

Answers

  • Here is how to create your own non-proxy contract class.  It can be used directly by other MSRS services.

     

    1. Open MSRS command prompt and create your new library:

     

    > dssnewservice -s:"SampleLibrary"

     

     

    2. Open the project

       a. Delete SampleLib.cs

       b. Add your DataContract Classes, DataMembers, and Operation Types.  Do as much of this work up front, because the proxy generation tool will create appropriate CopyTo, Clone, and Serialization methods for these types.  If you modify your contract later, you will need to keep these routines up-to-date.

     

    Example:

     

        /// <summary>

        /// The SampleLibrary State

        /// </summary>

        [DataContract()]

        public class SampleLibraryState

        {

            [DataMember]

            public string Name;

        }

    3. Compile

    4. Find the Proxy subdirectory under this project and open the proxy project

    a. Delete the manifest from the project

    5. Open AssemblyInfo.cs, replace this section

    #if NET_CF20

    [assembly: ServiceDeclaration(DssServiceDeclaration.Proxy, SourceAssemblyKey="cf.samplelibrary.y2007.m05, version=0.0.0.0, culture=neutral, publickeytoken=ff272b8" +

        "1e0a6ac96")]

    #else

    [assembly: ServiceDeclaration(DssServiceDeclaration.Proxy, SourceAssemblyKey="samplelibrary.y2007.m05, version=0.0.0.0, culture=neutral, publickeytoken=ff272b8" +

        "1e0a6ac96")]

    #endif

     

    With:

    In the 1.5 April release:

    [assembly: ServiceDeclaration(DssServiceDeclaration.NonDssService)]

     

    6. Open RoboticsSampleLibraryTypes.cs

                    a. Remove .Proxy from the namespace line.

    namespace Robotics.SampleLibrary

          b. In the Contract class, Delete the following static methods:

    ·         ServiceModel()

    ·         CreateService()

    7. Rename the Project to SampleLibrary

                    a. In Visual Studio Solution Explorer, rename “SampleLibrary.Y2006.M05.Proxy” to “SampleLibrary”

                    b. Open the Application properties,  change the AssemblyName to “SampleLibrary”

                    c. Open the Build properties, change the XML documentation file to "SampleLibrary.xml"

    8. Remove the original project

    a. Close Visual Studio

    b. delete …\bin\SampleLibrary.*

    b. Open Explorer to the SampleLibrary folder

    c. Delete all files and folders except for “Proxy”

    d. Move all files and subfolders from SampleLibrary\Proxy to SampleLibrary

    e. Compile SampleLibrary.csproj

    9. Add utility methods

    a. Create a static class in your project, or

    b. Add helper methods to your [DataContract] classes as necessary.

    c. Compile SampleLibrary.csproj

    10. Use the new SampleLibrary.dll from any other MSRS service.

                    a. You can include the [DataContract] classes as fields in your service state.

                    b. You can create new [DataContract] classes which inherit from the [DataContract] classes in this library dll.

     

     

    Sunday, May 13, 2007 11:07 PM

All replies

  •  

    Actually, I'm tempted to try out _only_ using the proxy.  You can definitely reference the proxy from both the service and its clients (doing so is suggested and supported for implementing the 'generic' contracts in RoboticsCommon.Proxy.dll).  In this case, you could consider dumping the original *Types.cs, and move your 'helper' functions into the proxy, then have your service (and its clients) reference this beefed-up proxy.

     

    The down side to doing so is 1) tools don't automatically support this, so you have a lot of manual one-time-setup work to do.  2) if the format of proxy DLLs is changed in subsequent Microsoft Robotics Studio versions, you'd have to manually port your proxy code since it is no-longer being auto-generated -- this may again be non-trivial.

     

    #aaron

    Friday, April 20, 2007 10:55 PM
  • Good question. The purpose of proxies is to define a separation between state and behavior that can be programmatically enforced and which defines a certain level of loose coupling between services. The basic idea here is of course to isolate behavior to be inside services and only exchange data between services. This separation is semantically similar to if you only exposed an XML Schema Definition or WSDL description of your service state.

     

    However, as you point out there are scenarios where it makes sense to define data types that define some level of helper processing over the data. The way I would suggest that you do that is to define a type DLL which exposes base types that everybody link against and the state types inherit from. While you want to be careful keeping the base types general in scope, this provides you exactly the same level of separation as if you used any of the common CLR types already defined.

     

    Henrik

    Saturday, April 21, 2007 4:09 PM
  • I'm not sure I fully understand your suggestion.

     

    Are you saying I should create just a library dll file (.cs) in a stand alone project, and define my state types in that file? And then in the actual service1state and service2state objects, just inherit from the types in the .dll?

     

    Does this mean that when service2 receives a service1state message from service1.proxy.dll, it will be able to call those member functions that were defined in the stand alone DLL?

     

    -Don

    Monday, April 23, 2007 7:56 PM
  • I'm wondering if anyone could possibly elaborate on this, possibly with a short example? This is becoming bigger and bigger of a problem with the increasing number of services I'm trying to run.

     

    Thanks,

    Don

    Friday, May 4, 2007 1:10 AM
  • Yes, this is a common issue, and a good sample would help tremendously.  We will add this to our scenarios and either post a sample on Channel or put it into the next CTP.  I'll post my preliminary work to this thread.


    David Lee

    Friday, May 4, 2007 8:39 PM
  • Here is how to create your own non-proxy contract class.  It can be used directly by other MSRS services.

     

    1. Open MSRS command prompt and create your new library:

     

    > dssnewservice -s:"SampleLibrary"

     

     

    2. Open the project

       a. Delete SampleLib.cs

       b. Add your DataContract Classes, DataMembers, and Operation Types.  Do as much of this work up front, because the proxy generation tool will create appropriate CopyTo, Clone, and Serialization methods for these types.  If you modify your contract later, you will need to keep these routines up-to-date.

     

    Example:

     

        /// <summary>

        /// The SampleLibrary State

        /// </summary>

        [DataContract()]

        public class SampleLibraryState

        {

            [DataMember]

            public string Name;

        }

    3. Compile

    4. Find the Proxy subdirectory under this project and open the proxy project

    a. Delete the manifest from the project

    5. Open AssemblyInfo.cs, replace this section

    #if NET_CF20

    [assembly: ServiceDeclaration(DssServiceDeclaration.Proxy, SourceAssemblyKey="cf.samplelibrary.y2007.m05, version=0.0.0.0, culture=neutral, publickeytoken=ff272b8" +

        "1e0a6ac96")]

    #else

    [assembly: ServiceDeclaration(DssServiceDeclaration.Proxy, SourceAssemblyKey="samplelibrary.y2007.m05, version=0.0.0.0, culture=neutral, publickeytoken=ff272b8" +

        "1e0a6ac96")]

    #endif

     

    With:

    In the 1.5 April release:

    [assembly: ServiceDeclaration(DssServiceDeclaration.NonDssService)]

     

    6. Open RoboticsSampleLibraryTypes.cs

                    a. Remove .Proxy from the namespace line.

    namespace Robotics.SampleLibrary

          b. In the Contract class, Delete the following static methods:

    ·         ServiceModel()

    ·         CreateService()

    7. Rename the Project to SampleLibrary

                    a. In Visual Studio Solution Explorer, rename “SampleLibrary.Y2006.M05.Proxy” to “SampleLibrary”

                    b. Open the Application properties,  change the AssemblyName to “SampleLibrary”

                    c. Open the Build properties, change the XML documentation file to "SampleLibrary.xml"

    8. Remove the original project

    a. Close Visual Studio

    b. delete …\bin\SampleLibrary.*

    b. Open Explorer to the SampleLibrary folder

    c. Delete all files and folders except for “Proxy”

    d. Move all files and subfolders from SampleLibrary\Proxy to SampleLibrary

    e. Compile SampleLibrary.csproj

    9. Add utility methods

    a. Create a static class in your project, or

    b. Add helper methods to your [DataContract] classes as necessary.

    c. Compile SampleLibrary.csproj

    10. Use the new SampleLibrary.dll from any other MSRS service.

                    a. You can include the [DataContract] classes as fields in your service state.

                    b. You can create new [DataContract] classes which inherit from the [DataContract] classes in this library dll.

     

     

    Sunday, May 13, 2007 11:07 PM
  • Are you serious?  This is nuts.

     

    Is this really the only way to provide state properties that use implementation logic?  If so, do the circus stunts Dave Lee described above still hold true for R3?

     

    Thanks,


    Dennis M. Knippel
    Thursday, June 23, 2011 4:30 AM
    Moderator
  • I think what you are talking about is by design. A Proxy cannot include any executable code because it is not clear what context the code should run in. For example, if the proxy refers to a service running on another computer, where should any executable code be run? In other words, a Proxy is a pure Data Contract. And code execution is inside the service and is only accessed via operation requests.

    Trevor

     

    Sunday, July 10, 2011 7:59 AM