Alex Meyer-Gleaves

on web services, wscf

Controlling your Service method implementation in WSCF.blue

I have added some new options to WSCF.blue that control how the methods in your service class are code generated. It was a post in the Discussions forum on our CodePlex site that prompted me to finally add the feature that I myself have wanted for some time now. The default service class code generated by WSCF.blue contains operation method implementations that throw a NotImplementedException. The issue with this approach is that you need to manually update the generated code to call another class that contains your actual service implementation, otherwise you will loose your implementation code during the regeneration process. You can now decide if you would like your service implementation to exist in a partial class or abstract class that can be defined in a separate file. These options can be found in the Service Method Implementation group in the Code Generation options dialog.

Options for Service Method Implementation

The first and default option is to generate method bodies that throw a NotImplementedException. Making this option the default keeps the behaviour consistent with previous builds of WSCF.blue. However, using this option will always result in your having to perform same manual modifications to the generated service class.

[System.ServiceModel.ServiceBehaviorAttribute()]
public class FooService : IFooService
{
    public virtual FooResponse Foo(FooRequest request)
    {
        throw new System.NotImplementedException();
    }
}

Selecting the partial class option will cause the generated service class to be marked as partial. It will also contain operation methods that call through to a partial method that can be defined in another partial class and in another file. This file must be created manually yourself, but once created it will remain untouched when you regenerate your service code.

[System.ServiceModel.ServiceBehaviorAttribute()]
public partial class FooService : IFooService
{
    public virtual FooResponse Foo(FooRequest request)
    {
        return FooImplementation(request);
    }
}

The naming convention for the partial method is the name of the operation method suffixed with Implementation. In the example above you can see the Foo operation method calls a FooImplementation method that is expected to be present in your partial class definition. You will receive a compiler error until you have defined your partial class containing the appropriate partial methods.

public partial class FooService
{
    protected FooResponse FooImplemenation(FooRequest request)
    {
        FooResponse response = new FooResponse();
        // Some web service processing code.
        return response;
    }
}

Your partial class definition should be created in a separate file to the service class that calls it. This will ensure you do not have to make any changes when regenerating your service code, which is obviously the very issue the option is designed to solve.

Because a partial class can be defined in a separate file, but must reside within the same project, an abstract class option was added that allows you to place your service implementation in another assembly. This option causes an abstract service class containing abstract operation methods to be code generated.

[System.ServiceModel.ServiceBehaviorAttribute()]
public abstract class FooService : IFooService
{
    public abstract FooResponse Foo(FooRequest request);
}

You can then inherit from the abstract service class and place your implementation in the overridden abstract methods. Similar to the partial class approach, this allows you to separate your implementation into another file that remains untouched when you regenerate your service code, but also allows for the implementation to be created in another assembly.

public class FooServiceImplemenation : FooService
{
    public override FooResponse Foo(FooRequest request)
    {
        FooResponse response = new FooResponse();
        // Some web service processing code.
        return response;
    }
}

Both the partial class and abstract class approaches are equally valid, and both result in the desired outcome of protecting your implementation code. The important points to remember are that when using the partial class option, your implementation class must have the same name as the code generated service class and must be defined in a file within the same project. When using the abstract class option, your implementation class cannot have the same name as the code generated service class but can be defined in a file that is not in the same project. Which you prefer to use entirely up to you and is probably a matter of taste for the most part.

I hope you find this feature useful, I know I certainly will. Please report any WSCF.blue bugs in the Issue Tracker and feel free to raise your suggestions in the Discussions forum.

profile
AUTHOR

Alex Meyer-Gleaves

I'm a software architect living in Australia (that island like continent in the southern hemisphere). I love Microsoft .NET and C#. I hate early mornings and bad drivers.