.Net Code Monkey RSS 2.0
 Tuesday, April 01, 2008

I'm sure most of us endeaver to keep the tightest scope possible for the members of classes we write. But I have a situation where I just can't seem to be able to keep the scope of members of my inherited class as tight as I would like.

What I am intending to create is a Job object that will inherit from a BaseJob object that will implement the IJob interface. While doing this I want to ensure the JobFactory member of the Job object is kept private and the Id member is public. Both of these members belong in the BaseJob object.

So I'll start with new assembly that will contain three interfaces; IJob, IIdentifyable and IJobFactory.

public interface IJob : IIdentifyable
{
    /// <summary>
    /// Gets or sets a reference to the factory that created the IJob object.
    /// </summary>
    IJobFactory JobFactory { get; set; }
}
/// <summary>
/// Represents the signature for an object that is identifyable
/// </summary> public interface IIdentifyable { /// <summary> /// Gets or sets a reference to the identity of the IJob object. /// </summary> int Id { get; set; } }

/// <summary>
/// Represents the signature required for a job factory.
/// </summary>
public interface IJobFactory
 {
     /// <summary>
     /// Creates an object that implements the IJob interface.
     /// </summary>
     /// <returns>Returns an object that implements the IJob interface</returns>
     IJob Create();

     /// <summary>
     /// Saves the current job
     /// </summary>
     void Save(IJob job);
 }

IJob has a member which will be used to hold a reference to an object (that implements the IJobFactory inteface) that created it. It will also have a Id member implemented through the IIdentifyable interface. IJobFactory has a method for returning a newly created object that implements the IJob interface and a method to save an object that implements the IJob interface. Both interfaces must be public as they need to be seen from outside the assembly. As far as I am aware you canot declare the scope of the methods in an interface so each will be of the same scope as the interface.

I now need to another new assembly which will contain a base class (BaseJob) for my Job object to inherit from. I create a reference to the interfaces assembly, and allow the BaseJob class will implement the IJob interface from it.

/// <summary>
/// The base class that all Job objects should inherit from.
/// </summary>
public abstract class BaseJob : IJob
{
    private int _id;
    private IJobFactory _jobFactory;

    #region IIdentifyable Members

    /// <summary>
    /// Represents the identity of an Job
    /// </summary>
    public int Id
    {
        get { return _id ; }
        set { _id = value; }
    }

    #endregion

    #region IJob Members

    /// <summary>
    /// Gets or sets a reference to the factory that created the IJob object.
    /// </summary>
    public IJobFactory JobFactory
    {
        get { return _jobFactory; }
        set { _jobFactory = value; }
    }

    #endregion

}

Now, I would like to set the scope of the BaseJob's Id and Jobfactory members as protected, do they can only be seen by objects that inherit from the BaseJob object. However if I try and make the scope any tighter then VS advises me of an error when I try to build.

Error 1 'BaseJob' does not implement interface member 'IJob.JobFactory'. 'BaseJob.JobFactory' is either static, not public, or has the wrong return type.

So as far as I can see it has to stay public. Any way on to my Job object now. In a third assembly, which has a reference to both the base class assembly and the interfaces assembly,  I create the Job class.

public class Job : BaseJob
{
    public Job(int id, IJobFactory jobFactory) : base()
    {
        base.Id = id;
        base.JobFactory = jobFactory;
    }
}

The Job class has a contructor which allows me to pass in the identity and the JobFactory which is used to create it ( I hope to write an post / question on dependency injection next!). My problem is I don't intend the JobFactory property of the Job object to be visiable outside the class code, so ideally I would like to scope it as private. However it is an inherited member that already has a scope of public. I can quite clearly see the member like so...

class TestClass
{
    Job _job;

    public TestClass()
    {
        _job = new Job();
        _job.JobFactory = ...;
    }
}

The only way I can see to hide the member is by overriding the JobFactory member to the Job object with the new modifier like so.

private new IJobFactory JobFactory
{
    get { return base.JobFactory; }
}

Is this really the best way to go about this, or am I doing something fundementally wrong? Your comments appreciated!

 

Tuesday, April 01, 2008 8:35:00 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | C# | Inheritance | Interfaces | Scope
 Monday, March 31, 2008

Background

As part of an ongoing project where a light weight client application needs to communicate with a database via a webservice I have been trying to get my head around a the best way to encapsulate data within custom objects and pass it from the client 's GUI to the Web Service's Data Access layer without replicating too much code or having the the client hold a reference to the same assembly as the webservice.

The intention is for the client application to have 3 layers, the presentation layer, a Business Entity / Business Logic layer and an Webservice Adapter layer. The Webservice will have the WebService layer, it's own Business Entity / Business Logic layer and a Data Access layer.

Initial Thoughts

My initial thoughts were to create an assembly which would hold a set of interfaces that will describe the business entities that both parts of the application would use. For example the interface fot the job object would be:

public interface IJob
{
    int Id;
    string CreatedBy;
    DateTime CreatedOn;
    .
    .
    DateTime LastAccessed;
}

This would require that both pairs of business entity assemblies would need to have a reference to the assembly. My plan was then to return from the webservice's webmethods the interface rather than the object. For example.

[WebMethod]
public IJob GetJobById(int id)
{
.
.
}

My plan was then bind the form controls to the properties of the interface but among a couple of minor flaws in my plan, there was one big one... It appears that you can not return an interface from a web service. I assume do to it not being serialisable. A little research later it appears that a better way would be to would be to use a shared base class for the business entities on both sides of the void, so to speak. So back to the drawing board slightly..

Second Thoughts

So now I'm thinking I need to create an abstract base class for the objects in the business entitiy assemblies in both the client and the webservice to inherit from. If I ensure the base classes implement the interfaces, then I can still bind my controls to the interfaces properties. So ignoring the various properties of the class I now have a bas class that implements the previosu

protected abstract class BaseJob : IJob
{
.
.
}

So now the Job class in each business entity layer will inherit from the BaseJob abstract class which implements the IJob interface.

public class Job : BaseJob
{
.
.
}

So this means that now rather than just having a reference to the assembly with the interfaces in for each business entity assembly I now have a reference to the base class assembly too. Is this really the way I want to go?

To be continued...

Monday, March 31, 2008 3:30:16 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | C# | Inheritance | Interfaces | Web Services

Well it has been a steep learning curve of languages and syntax of the last two years since I started at NewLook. I came in with only HTML and what I thought was a reasonable knowledge of VB script in the form of classic ASP. Since then it's been Web and Windows programming in VB.Net and last year a move to C#. So what next?

Well, our team are aware that there is a plan in the company to have a new team of Java developers employed in the not too distant future. So I guess at some point it will be prudent to get a bit of back ground knowledge of this Java stuff.

Now I get a bit scared when thinking about learning another new programming language, incase it dilutes what little knowledge I have of my other languages. But I guess in reality, apart from forgetting not to put a semi-colon here and a curly brace there for the first 10 minutes of reworking an old project in another language, there is probably no disadvantage other than the time to learn the new syntax or new IDE to write it in. Infact from reading other developers blogs it appears it can help to improve your programming prowess in your original languages by exposing you to different architectures and ways of going about tackling problems.

What better way to give it a go than a need arising from an actual project! Seeing as we use a few Oracle products it seemed logical to find the JDeveloper set up file on the network and install and use that. I always find it disconcerting the way that you just unzip the files and flop them in a folder and create a shortcut to your start menu, if you feel like it. There is something to be said for MSI installer packages; if they complete without failure, you at least you have some confidence that the app will run! But run it did, and apart from having to point a setting to the folder that contained what I assume was the compiler, it was all good.

To be continued...

Monday, March 31, 2008 2:21:44 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
Java
Archive
<April 2008>
SunMonTueWedThuFriSat
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
Blogroll
 Clemens Vasters
 Harry Pierson
Passion * Technology * Ruthless Competence
 Joshua Flanagan
A .NET Software Developer
 Michael Schwarz's Blog
Developing applications on the Microsoft platform since Windows 3.1!
 Omar Shahine
Yet another Microsoft blogger
 Scot GU
Scott Guthrie lives in Seattle and builds a few products for Microsoft
 Scott Hanselman
Programming Life and the Zen of Computers
 Tom Mertens
Tom's corner
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2009
Duane Wingett
Sign In
Statistics
Total Posts: 21
This Year: 0
This Month: 0
This Week: 0
Comments: 8
Themes
Pick a theme:
All Content © 2009, Duane Wingett
DasBlog theme 'Business' created by Christoph De Baene (delarou)