.Net Code Monkey RSS 2.0
 Saturday, November 15, 2008

Another discovery today, courtesy of Google finding Rik Robinson's Blog is String.TrimStart() and String.TrimEnd().

To trim a leading slash of a string or path use:

myString = myString.TrimStart(new char[]{'\\', '/'}); 

 

To trim a trailing slash of a string or path use:

myString = myString.TrimEnd(new char[]{'\\', '/'}); 

 

I had previously been using a much more long-winded approach. Cheers Rik for bringing that to my attention.

Saturday, November 15, 2008 11:17:15 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | C#

I have recently experienced a JavaScript errror incident when I started using Roles and Membership in a website for the first time.

IE6 reported a syntax error at Line 5 after adding a SiteMapDataSource and Asp.Net Menu controls to the page. The menu would not work I guess due to the JavaScript error.

A quick Google, led me to this page which led me to try adding the following code into my web config

  </system.web>
  
  <!-- Prevent JavaScript Errors, caused by web resource can't be accessed by current user. -->
  <location path="webresource.axd">
    <system.web>
      <authorization>
        <allow users="*"/>
      </authorization>
    </system.web>
  </location> 

</configuration>

This appeared to remove the error, I am assuming by allowing the web resource JavaScript to be accessed by all users.

 

Saturday, November 15, 2008 10:54:42 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | Asp.Net | Authorization | Config Files | Errors | JavaScript | Membership | Roles
 Sunday, October 26, 2008

It’s been quite a while since I have written anything (yes I really need to finish the last article!), but this morning I came across a problem where I need to provide separate database connections for different website visitors who will be using the same underlying .Net TableAdapters. So I thought I’d write about it.

 

Background:

I have set up my Sql Server 2005 database to have four roles; DbAdmin, WebAdmin, ProductSeller, ProductBuyer. Each of these roles has been given different levels of read / write / execute permission on the various database objects. It is my intention to let the built in .Net 2.0 Membership and Roles objects handle assigning of roles (mirroring the four database roles) to all of the website visitors.

 

As far as I know to make use the database roles properly I will need four separate database logins and database users, and hence in my application I will need four different connection strings.

 

Problem:

The problem is that I could not see any exposed properties of a table adapter to allow the connection to be changed dynamically.

 

My solution:

My solution is to set up the application to have four connection strings for the four database logins, and create an overridden constructor for each TableAdapter that requires role specific database connections.

 

Setting up the database

 

For the purpose of this example I have created the following database logins.

Login

Login Name

Password

Database administrator

MyWesite_DbAdministrator

da1

Website administrator

MyWesite_WebAdministrator

wa1

Product Seller

MyWesite_ProductSeller

ps1

Product Buyer

MyWesite_ProductBuyer

pb1

 

The database roles I have created are as follows.

Role name

Description

DatabaseAdmin

The role assigned to the database administrator

WebsiteAdmin

The role assigned to the web site administrator

ProductSeller

The role assigned to users who can list a product on the site.

ProductBuyer

The role given to public users of the site

 

 

Application Architecture Overview:

The application is written in a layered architecture with the web front end having visibility of the Interfaces layer and the Services layer, and the Services layer having visibility of the Interfaces layer, the Business Entities layer, and the Data Access layer. The data access layer contains all the typed datasets and any other database related objects.

 

Connection strings:

The four connection strings are entered into the Settings tab of the Properties page of the DataAccess project.

 

Name

Type

Scope

Value

> 

DatabaseAdminCon…

(Connection…

Application

Data Source=…

 

WebsiteAdminConn…

(Connection…

Application

Data Source=…

 

ProductSellerConne…

(Connection…

Application

Data Source=…

 

ProductBuyerConne…

(Connection…

Application

Data Source=…

*

 

 

 

 

 

Creating the connection

As we need to provide a role specific connection to the table adapter we need an object that can create and return a connection.

using System;
using System.Data.SqlClient;
using ConnectionStrings = MyProject.DataAccess.Properties.Settings;

namespace MyProject.DataAccess
{
    public class DatabaseConnection
    {
        /// <summary>
        /// Returns a connection for use with the role name passed in
        /// </summary>
        /// <param name="roleName">
        /// Represents the name of the role to get connection string for.
        /// </param>
        /// <returns>
        /// Returns a Sql Server connection.
        /// </returns>
        public SqlConnection GetConnectionForRole(string roleName)
        {
            SqlConnection connection = null;
            string connectionString = string.Empty;

                connectionString = GetConnectionStringForRole(roleName);
                connection = new SqlConnection(connectionString);
            return connection;

        }

        /// <summary>
        /// Returns a connection string based on the passed in rolename.
        /// </summary>
        /// <param name="roleName">
        /// Represents the name of the role to get connection string for.
        /// </param>
        /// <returns></returns>
        private string GetConnectionStringForRole(string roleName)
        {
            string connectionString = string.Empty;            

            switch (roleName)
            {
                case "DatabaseAdmin":
                    connectionString = ConnectionStrings.Default.DatabaseAdminConnectionString;
                    break;

                case "WebsiteAdmin":
                    connectionString = ConnectionStrings.Default.WebsiteAdminConnectionString;
                    break;

                case "ProductSeller":
                    connectionString = ConnectionStrings.Default.ProductSellerConnectionString;
                    break;

                case "ProductBuyer":
                    connectionString = ConnectionStrings.Default.ProductBuyerConnectionString;
                    break;

                default:
                    throw new ArgumentOutOfRangeException("roleName", "Unknown role name encountered.");
            }

            return connectionString;
        }

    }
}

 

Default Constructor:

Next we need to look at the TableAdapter and create a constructor that overrides the default non parametricised constructor. The default constructor for our table adapter looks like this.

[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public MyTableAdapter() {
    this.ClearBeforeFill = true;
}

 

New Constructor:

To override this constructor we are going to take advantage of .Net 2.0’s partial classes. Using these we do not have to modify the auto-generated code of the dataset, and neither do we have to attempt to create a class that inherits from the dataset.

using System;
using System.Data.SqlClient;

namespace MyProject.DataAccess.ApplicationDataSetTableAdapters
{
    public partial class MyTableAdapter: System.ComponentModel.Component
    {
        /// <summary>
        /// Used to provide an overridden constructor for the MyTableAdapter
        /// allowing a connection to be passed in.
        /// </summary>
        /// <param name="sqlConnection"></param>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public MyTableAdapter (SqlConnection sqlConnection)
        {
            this.ClearBeforeFill = true;
            this.Connection = sqlConnection;
        }
    }
}

 

We take care to set the connection via the “Connection” property rather than just setting the _connection fields as the auto-generated "Connection" property ensure all adapter commands get the correct connection assigned to them, see below.

[System.Diagnostics.DebuggerNonUserCodeAttribute()]
 internal System.Data.SqlClient.SqlConnection Connection {
     get {
         if ((this._connection == null)) {
             this.InitConnection();
         }
         return this._connection;
     }
     set {
         this._connection = value;
         if ((this.Adapter.InsertCommand != null)) {
             this.Adapter.InsertCommand.Connection = value;
         }
         if ((this.Adapter.DeleteCommand != null)) {
             this.Adapter.DeleteCommand.Connection = value;
         }
         if ((this.Adapter.UpdateCommand != null)) {
             this.Adapter.UpdateCommand.Connection = value;
         }
         for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1)) {
             if ((this.CommandCollection[i] != null)) {
                 ((System.Data.SqlClient.SqlCommand)(this.CommandCollection[i])).Connection = value;
             }
         }
     }
 }

 

Initialising the TableAdapter

So now the code for accessing the adapter should look something like this.

/// <summary>
 /// Used to add an object that implements the IMyItem interface to the database.
 /// </summary>
 /// <param name="product">
 /// Represents the object implementing the IMyItem interface to add to the database.
 /// </param>
 void IMyItem.AddToDatabase(IMyItem product)
 {
     ApplicationAdapters.MyTableAdapter myTableAdapter = null;
     SqlConnection connection = null;
     try
     {
         connection = SqlServerConnectionService.GetConnectionForRole(RoleName);
         myTableAdapter = new ApplicationAdapters. MyTableAdapter (connection);
         MyTableAdapter.Add(product.Id, product.Name);
     }
     catch (Exception ex)
     {
         throw ex;
     }
     finally
     {
         SqlServerConnectionService.CloseConnection(connection);
         connection.Dispose();
         myTableAdapter.Dispose();
     }
 }

 

Connection Handling:

This code still allows the adapter to open and close the connection as necessary, we have just provided the connection we want. This approach has allowed me to ensure that a user logged in as a ProductBuyer should not have the permission to call procedures they shouldn’t even if I end up with a bug in the website code that allows a non authorised user to reach an administration page with add / update / delete functions.

 

As always your opinions and comments on this subject or the approach taken to overcome the problem are most welcome. I hope some one may find this useful.

 

Foot Note:

Some error handling in code has been omitted for sake of clarity

 

Sunday, October 26, 2008 3:34:07 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | Asp.Net | C# | Sql Server | Connection Strings | Database
 Saturday, April 12, 2008

I'm sure many of you are aware that you can override the connection string settings in your DataAccess layer of your web application with connection string settings in your Web.Config. We found this out recently and found it very useful in an intranet application at work recently. However this week one of the other developers required that he could override a setting the BusinessEntity layer of his application from the App.Config in the console layer.

A quick chat with Mr Google didn't turn up a solution for this, so with this in mind all three of us quickly tried to return a working solution. I'm going to try to give an example of what we did, incase it something others may find of use. First we create a solution with two class library projects within it. The first will simulate the DataAccess layer and the second will simulate the BusinessEntity layer in an application. In the BusinessEntity project we will create a reference to the DataAccess project.

Starting with the DataAccess project we will add an App.Config file by creating a setting called "MySetting" in the Settings tab of the project Properties. The setting scope will be set to Application.

This creates a new sectionGroup called applicationSettings and a new section in the App.Config file and places the new setting in their too.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" 
type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > <section name="Playground.ConfigurationOverride.DataAccess.Properties.Settings"
type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" /> </sectionGroup> </configSections> <applicationSettings> <Playground.ConfigurationOverride.DataAccess.Properties.Settings> <setting name="MySetting" serializeAs="String"> <value>Setting in DataAccess</value> </setting> </Playground.ConfigurationOverride.DataAccess.Properties.Settings> </applicationSettings> </configuration>

Next we will add a simple class to the DataAccess project with a single static method that will return the value of the setting we have just created.

using System;

namespace Playground.ConfigurationOverride.DataAccess
{
    public static class SettingsHelper
    {
        public static string GetMySetting()
        {
            return Properties.Settings.Default.MySetting;
        }
    }
}

Next we will create anothe simple class, SettingsGetter, in the but in the BusinessEntity layer this time. It will just return the value returned from the SettingsHelper class in the DataAccess layer.

using System;

namespace Playground.ConfigurationOverride.BusinessEntity
{
    public static class SettingsGetter
    {
        public static string GetDataAccessSettingValue()
        {
            return DataAccess.SettingsHelper.GetMySetting();
        }
    }
}
Next we need to create a presentation layer. So first off we will create a small web application and add it to the solution, and grab a reference to the BusinessEntity layer. Set the web site as the startup project. We will also add a Label to the default webform and a Button. In the Page_Load handler method populate the label text from the business entity method.
protected void Page_Load(object sender, EventArgs e)
 {
     uxSettingsLabel.Text = 
         Playground.ConfigurationOverride.BusinessEntity.SettingsGetter.GetDataAccessSettingValue();
 }

...and run the application, and allow the Web.Config file to be created. The value of the setting in the DataAccess App.Config file should be displayed.

 

More to follow soon...

Saturday, April 12, 2008 7:03:24 PM (GMT Standard Time, UTC+00:00)  #    Comments [2] -
.Net | Asp.Net | C# | Config Files | XML
 Friday, April 11, 2008

Back to Part 2

Review Of Progress So Far

So, to date we have created an interface for our ShapeFactory and any other shape factory to implement, an enumeration that represents all the available shapes we may wish to build, and a factory class that can build any of our two current shapes. The next step is to create a graphical user interface that will call the factory and receive a couple of shape objects for it's trouble.

The Client Gets What They Deserve

Next we need a client to display the shapes, so for simplicity we are going to create a small Windows Forms project called WindowsApplication and add it to the solution. The project will have a single form called Main (700x550) which will have a picture box (uxPictureBox) and a button, uxDrawButton.

We now need to add a handler for the Draw Button and declare a Bitmap and a Graphics object at the top of the class. In the form constructor we will initialise the bitmap to a new instance which will be the size of the PictureBox. We will then create the Graphics object from the Bitmap.

In the button handler method we will clear the graphics object to a white background.

public partial class Main : Form
 {
     private Bitmap _bitmap;
     private Graphics _graphics;

     public Main()
     {
         InitializeComponent();

         _bitmap = new Bitmap(uxPictureBox.Width, uxPictureBox.Height);
         _graphics = Graphics.FromImage(_bitmap);
         uxPictureBox.Image = _bitmap;
     }

     private void uxDrawButton_Click(object sender, EventArgs e)
     {
         _graphics.Clear(Color.White);
     }
 }

We now need a collection to hold our shapes, so we will declare a list of objects that implement IShape at the top of the class, and to do this we will need to provide a reference to the ShapeInterfaces project. At the same time add a reference to the Factories project and import the namespaces for both projects at the top of the form code.

using System.Text;
using System.Windows.Forms;
using Playground.ShapeMaker.Factories;
using Playground.ShapeMaker.ShapeInterfaces;

namespace Playground.ShapeMaker.WindowsApplication
{
    public partial class Main : Form
    {
        private Bitmap _bitmap;
        private Graphics _graphics;
        private List<IShape> _shapes;

        public Main()
        {

Next we need to add two method stubs that are void of return values, AddShapes() and DrawShapes(). Surprisingly, AddShapes() will take responsibility for adding new shapes to our list and DrawShapes() will draw those shapes. We will add a line to create an instance of our list in the constructor and below that we will place a call to the AddShapes() method. We will place a call in the button handler to the DrawShapes() method, below the line that clears the graphics to a white background. Follow this with a refresh of the PictureBox.

public Main()
 {
     InitializeComponent();
     _bitmap = new Bitmap(uxPictureBox.Width, uxPictureBox.Height);
     _graphics = Graphics.FromImage(_bitmap);
     uxPictureBox.Image = _bitmap;

     _shapes = new List<IShape>();
     AddShapes();
 }

 /// <summary>
 /// Handles the draw button pressed event.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void uxDrawButton_Click(object sender, EventArgs e)
 {
     _graphics.Clear(Color.White);
     DrawShapes();
uxPictureBox.Refresh(); }

In the AddShapes() method we need to create a new instance of our ShapeFactory object. Then using the ShapeFactory object add two shapes, a circle and a rectangle to the list.

 /// <summary>
 /// Adds shapes to the list
 /// </summary>
 private void AddShapes()
 {
     ShapeFactory shapeFactory = new ShapeFactory();
     _shapes.Add(shapeFactory.CreateShape(Shape.Circle));
     _shapes.Add(shapeFactory.CreateShape(Shape.Rectangle));
 }

Because we know that the shapes Implement the IShape interface we have a contract that says we can call the Draw() methods on any of these shapes. These objects will then take the responsibility for drawing them selves. So in the DrawShapes() method all we need to do is iterate through all the shapes in the list and call each shapes Draw() method.

 /// <summary>
 /// Draws the shapes in the list
 /// </summary>
 private void DrawShapes()
 {
     foreach(IShape shape in _shapes)
     {
         shape.Draw();
     }
 }

And that would be it... apart from we haven't added any working code into the Draw() methods of each concrete object yet!

A Change In The Contract

Apart from the fact there is no code in the concrete objects to actually draw them selves, I have just noticed the need to be able to pass the Graphics object into each shape object, so we need to go back to the interfaces and change the signature for the Draw() method.

So if we take a look in the IShape interface we need to be able to pass in a Graphics object as a method parameter.

public interface IShape
 {
     /// <summary>
     /// Represents the center of the shape
     /// </summary>
     Point Center { get; set;}

     /// <summary>
     /// The method used to draw the shape
     /// </summary>
     /// <param name="graphics">A reference to the Graphics object to draw the shape on.</param>
     void Draw(Graphics graphics);
 }

And while we are in this project I think we will take the opportunity to extend the CreateShape() method signature in the IShapeFactory interface, too. We are going to add a center point parameter; this will allow us to position the shape where we like.

public interface IShapeFactory
 {
     /// <summary>
     /// Use this method to create a shape.
     /// </summary>
     /// <param name="shape">Indicates the type of shape to be made.</param>
     /// <param name="center">Indicates the center point of the shape.</param>
     /// <returns>An object that implements the IShape interface.</returns>
     IShape CreateShape(Shape shape, Point center);
 }

A quick build of the project will highlight where our change in interface has broken the contract between it and the objects that implement it so in the BaseShape object we need to add a Graphics parameter into the Draw() method. This will be the same in the Rectangle and the Circle class.

public abstract void Draw(Graphics graphics);

In the ShapeFactory class we need to extend the CreateShape(), CreateCircle() and CreateRectangle() methods signatures to include the center point parameter. Then in the CreateShape() method we need to pass the center point parameter on to the worker method calls.

/// <returns>A shape object that implements IShape.</returns>
public IShape CreateShape(Shape shape, Point center)
{

In the two worker methods, CreateCircle() and CreateRectangle() we will populate the object's Center property with the value from the center parameter passed in.

 /// <summary>
 /// This method creates a circle object.
 /// </summary>
 /// <returns>A shape object that implements ICircle.</returns>
 private ICircle CreateCircle(Point center)
 {
     Circle circle = new Circle();
     circle.Center = center;
     circle.Diameter = 50;
     return (ICircle)circle;
 }

 /// <summary>
 /// This method creates a rectangle object.
 /// </summary>
 /// <returns>A shape object that implements IRectangle.</returns>
 private IRectangle CreateRectangle(Point center)
 {
     BusinessEntity.Rectangle rectangle = 
         new BusinessEntity.Rectangle();
     rectangle.Center = center;
     rectangle.Size = new Size(400, 200);
     return (IRectangle)rectangle;
 }

Then back in the form code we need to alter the calls to the ShapeFactory CreateShape() methods to include a center position

 /// <summary>
 /// Adds shapes to the list
 /// </summary>
 private void AddShapes()
 {
     ShapeFactory shapeFactory = new ShapeFactory();
     _shapes.Add(shapeFactory.CreateShape(Shape.Circle, new Point(250,250)));
     _shapes.Add(shapeFactory.CreateShape(Shape.Rectangle, new Point(350, 200)));
 }

 /// <summary>
 /// Draws the shapes in the list
 /// </summary>
 private void DrawShapes()
 {
     foreach(IShape shape in _shapes)
     {
         shape.Draw(_graphics);
     }
 }

Back to the Drawing Board

So finally we can get back into the concrete shape classes and write the code that will draw the shape.

So let us look at the Circle's Draw() method first. We'll add the code to allow the Circle to draw it's self.

 /// <summary>
 /// Use this method to draw the shape
 /// </summary>
 public override void Draw(Graphics graphics)
 {
     Pen pen = new Pen(Color.DarkGray, 0);
     int left = (int)Center.X - (Diameter/2);
     int top = (int)Center.Y - (Diameter/2);

     System.Drawing.Rectangle outlineRectangle =
         new System.Drawing.Rectangle(left, top, Diameter, Diameter);
     graphics.DrawEllipse(pen, outlineRectangle);
 }

And the same for the Rectangle.

 /// <summary>
 /// Use this method to draw the shape
 /// </summary>
 public override void Draw(Graphics graphics)
 {
     Pen pen = new Pen(Color.Red, 0);
     int left = (int)Center.X - (Size.Width / 2);
     int top = (int)Center.Y - (Size.Height / 2);

     System.Drawing.Rectangle outlineRectangle =
         new System.Drawing.Rectangle(left, top, Size.Width, Size.Height);
     graphics.DrawRectangle(pen, outlineRectangle);
 }

Now we need to make sure we have set the start up project to be the windows application and we should be good to go!

Conclusions

Now I'm certain that the application architecture and the code may not be laid out to best practises, and I'm aware there are plenty of parts that could have been better thought out and implemented, but really I just wanted to get a simple factory based application down on paper, so to speak, to get it a little clearer in my mind.

If any of these articles have helped you or planted the seed of inquisitiveness in your mind to find out more about factories then that can only be a good thing. If there is anything I have done in this article that is quite clearly incorrect or bad practise, please feel free to leave a comment. Any constructive feed back is appreciated.

The next step will be to make the objects prinatable. But until then, have fun!

Part 1 | Part 2

2008-04-11_ShapeMaker.zip (103.25 KB) <- Solution files all zipped up.
Friday, April 11, 2008 8:44:42 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | C# | Classes | Factory Pattern | Inheritance | Interfaces
 Thursday, April 10, 2008

Back to Part 1

Review Of Progress So Far

So far we have two concrete shape classes, Circle and Rectangle that derive from a base shape class. The base shape class implements the IShape interface and the concrete classes implement in turn the IShape interface as well as their respective shape interfaces. The next step is to create a factory class to create our shapes.

Working In The Factory

So, we need to add to the solution, another new class library project which we will call Factories. This will house our ShapeFactory class. The ShapeFactory class will be responsible for creating our shape objects. It will be able to create and return an object that implements the IShape interface. So far we have ensured that both our circle and rectangle inherently implement the IShape interface for two reasons. One, because they both derive from the BaseShape object and we know that implements IShape, and two, because they implement ICircle and IRectangle which in turn implements IShape, as well. (Maybe some one with a little more experience than I, could advise if this is an acceptable practise. -> I can't see why not!)

But before we create our ShapeFactory we have one more thing to do. Because we may want to use more than one factory in the future to create our shapes we are first going to create another interface, which will describe what a ShapeFactory need to create some shape objects. This will be the IShapeFactory interface, and we are going to add that for the sake of simplicity to our ShapeInterfaces project

using System;

namespace Playground.ShapeMaker.ShapeInterfaces
{
    public interface IShapeFactory
    {
        /// <summary>
        /// Use this method to create a shape.
        /// </summary>
        /// <returns>An object that implements the IShape interface.</returns>
        IShape CreateShape();
    }
}

As you can see we have determined that any factory that implements IShapeFactory will have to contain a method that returns an object implementing IShape. The problem is, how do we determine what sort of shape we want to get? Well even though we only have two shapes at the moment for future expansion we will need an enumeration to represent these. As enumeration is to be used in every class that implements IShapeFactory and will need to be a parameter in the CreateShape method, it seems logical to me to place the enumeration in the ShapeInterfaces project. If any one can advise whether this is good practise or not, please do! So, let us add the Shape enumeration.

using System;

namespace Playground.ShapeMaker.ShapeInterfaces
{
    /// <summary>
    /// Represents the types of shapes that can be made
    /// </summary>
    public enum Shape
    {
        /// <summary>
        /// Indicates the shape is to be a circle
        /// </summary>
        Circle,

        /// <summary>
        /// Indicates the shape is to be a rectangle
        /// </summary>
        Rectangle
    }
}
We can now modify the CreateShape method of the IShapeFactory interface to accept a Shape enumerated value.
public interface IShapeFactory
 {
     /// <summary>
     /// Use this method to create a shape.
     /// </summary>
     /// <param name="shape">Indicates the type of shape to be made.</param>
     /// <returns>An object that implements the IShape interface.</returns>
     IShape CreateShape(Shape shape);
 }

So it's back to the Factories project now to create the ShapeFactory class that will provide us with some shapes. To create some shapes we need to add a reference to both the BusinessEntity and the ShapeInterfaces projects into the Factories project. After adding our new ShapeFactory class into the Factories project we need to import the BusinessEntity and the ShapeInterfaces namespaces into the top of it. We now need to make the ShapeFactory class implement IShapeFactory.

using System;
using Playground.ShapeMaker.BusinessEntity;
using Playground.ShapeMaker.ShapeInterfaces;

namespace Playground.ShapeMaker.Factories
{
    public class ShapeFactory : IShapeFactory
    {

        #region IShapeFactory Members

        public IShape CreateShape(Shape shape)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }
}

We are now going to create a pair of private methods that will create our two shapes. Although these methods will create two concrete objects the methods will return not the objects but their interfaces. First though we will just create the method stubs. Then we will modify the CreateShape() method to call one or the other of these two methods depending upon the enumerated value passed in.

#region IShapeFactory Members

 /// <summary>
 /// Creates a shape and returns it.
 /// </summary>
 /// <param name="shape">Indicates the shape to create.</param>
 /// <returns>A shape object that implements IShape.</returns>
 public IShape CreateShape(Shape shape)
 {
     IShape createdShape = null;
     switch (shape)
     {
         case Shape.Circle:
             createdShape = CreateCircle();
             break;

         case Shape.Rectangle:
             createdShape = CreateRectangle();
             break;

         default:
             throw new Exception("Unknown shape encountered in CreateShape() method.");
     }
     return createdShape;
 }

 #endregion

 /// <summary>
 /// This method creates a circle object.
 /// </summary>
 /// <returns>A shape object that implements ICircle.</returns>
 private ICircle CreateCircle()
 {

 }

 /// <summary>
 /// This method creates a rectangle object.
 /// </summary>
 /// <returns>A shape object that implements IRectangle.</returns>
 private IRectangle CreateRectangle()
 {

 }

We have used switch / case to select which method will create our shape object. Notice that we use the default case to throw an exception if we encounter a shape that we haven't catered for. This is in case at any time the shape enumeration is extended to provide more shapes. Notice also that although the CreateShape() method returns an object that implements IShape, the two worker methods return ICircle and IRectangle. This works because both ICircle and IRectangle both implement the IShape interface, and that is what CreateShape() will return.

Anyway let us crack on and 'flesh out' the CreateCircle() worker method! Because our shapes using the System.Drawing namespace, our factory that is going to create these will need to also. So we need to add a reference to and import that namespace for the ShapeFactory. (Incidentally have you noticed the more you look at the word "circle" the more wrong it looks!)

 /// <summary>
 /// This method creates a circle object.
 /// </summary>
 /// <returns>A shape object that implements ICircle.</returns>
 private ICircle CreateCircle()
 {
     Circle circle = new Circle();
     circle.Center = new Point(250,250);
     circle.Diameter = 50;
     return (ICircle)circle;
 }

Now I would normally use constructor in my code, but this example isn't to show best practise of constructing objects, so I am going to construct my objects using the properties today. You will probably also notice that I am casting the newly constructed Circle object to the type of ICircle before returning it. You don't need to do this but I believe it is good practise. (Can any one confirm this please?)

At this point I have just realised an error with choosing a rectangle for a shape, due to a conflict with the System.Drawing.Rectangle object. Well we could change the shape to a square or a triangle.... but we have got this far, so I am going to stick with it. It will however mean there will be some ugly code with the BusinessEntity namespace forced in here and there!!!

 /// <summary>
 /// This method creates a rectangle object.
 /// </summary>
 /// <returns>A shape object that implements IRectangle.</returns>
 private IRectangle CreateRectangle()
 {
     BusinessEntity.Rectangle rectangle = 
         new BusinessEntity.Rectangle();
     rectangle.Center = new Point(300, 300);
     rectangle.Size = new Size(400, 200);
     return (IRectangle)rectangle;
 }

Now that should be it for our ShapeFactory for the moment. If all has gone well for you then your project should build without errors.

To sum up we have created an interface for this and any other shape factory to implement, an enumeration that represents all the available shapes we may wish to build, and a factory class that can build any of our two current shapes. the next step is to create a graphical user interface that will call the factory and receive a couple of shape objects for it's trouble.

Part 3

Thursday, April 10, 2008 6:28:13 PM (GMT Standard Time, UTC+00:00)  #    Comments [2] -
.Net | C# | Classes | Factory Pattern | Inheritance | Interfaces

Background

Recently I have been reading quite a bit about Factory Patterns and Inversion of Control (IOC). However like most principles that are new to me I often find them very hard to visualise at first, and even harder to put them into practise. So I am going to try a simple application using what I believe to be a Factory Pattern. The aim of the game will be to use a factory to produce shapes that will be drawn using .Net's GDI classes in a Windows form application.

This article assumes that the reader is already comfortable with the use of interfaces and inheritance in classes.

The files created in this article can be downloaded from here: 2008-04-11_ShapeMaker.zip (103.25 KB) 

Interfaces

The first thing I'm going to do is to create a Blank Solution, using Visual Studio 2005, which I am going to call ShapeMaker. To this solution I am going to add a New Project which will be a Visual C# Class Library which I am going to call ShapeInterfaces.

I'll close and delete the default Class1.cs class file before I proceed. I shall now add a new Interface called IShape and remove the two unused using statements. To the IShape interface I am going to add a System.Drawing.Point property called Center and import it's namespace after first adding a reference to the System.Drawing assembly. I shall then add a method that is void of a return type and call it Draw().

using System;
using System.Drawing;

namespace Playground.ShapeMaker.ShapeInterfaces
{
    public interface IShape
    {
        /// <summary>
        /// Represents the center of the shape
        /// </summary>
        Point Center { get; set;}

        /// <summary>
        /// The method used to draw the shape
        /// </summary>
        void Draw();
    }
}

All shapes that I intend to create will implement this interface. The Center property will define the center point of the shape, and the Draw() method will allow any user interface to know that when it is required to draw the shape it can call this method and the shape will be responsible for drawing it self.

I'm now going to add two more interfaces which will both implement the IShape interface, the ICircle which will also have a integer Diameter property...

using System;
using System.Drawing;

namespace Playground.ShapeMaker.ShapeInterfaces
{
    public interface ICircle : IShape
    {
        /// <summary>
        /// Represents the diameter of the circle
        /// </summary>
        int Diameter { get; set; }
    }
}

...and the IRectangle which will have a Size property.

using System;
using System.Drawing;

namespace Playground.ShapeMaker.ShapeInterfaces
{
    public interface IRectangle : IShape
    {
        /// <summary>
        /// Represents the size of the rectangle
        /// </summary>
        Size Size { get; set;}
    }
}

Base Classes

I'm now going to add another class library project to the solution which will be my BusinessEntity layer, from which I will also delete the default Class1 class. To the BusinessEntity project I am going to add a folder called BaseClasses. I would probably normally use a separate project for my base classes but for clarity of this example I shall place them in this folder.

To the BaseClassses folder I am going to add a class that all my shape entities will inherit from. I shall call this BaseShape. As I intend for BaseShape to implement the interface IShape I need to add a reference to the ShapeInterfaces project from the BusinessEntity project, and then import the namespace into the BaseShape class.

using System;
using Playground.ShapeMaker.ShapeInterfaces;

namespace Playground.ShapeMaker.BusinessEntity.BaseClasses
{
    public abstract class BaseShape : IShape
    {

    }
}

We have declared the class as abstract as we do not want this class to be able to be constructed. It will just be used a s a base for other classes to derive (inherit) from. Right clicking on the interface name and selecting Implement Interface from the context menu...

... should inject the following code into the class.

#region IShape Members

 public System.Drawing.Point Center
 {
     get
     {
         throw new Exception("The method or operation is not implemented.");
     }
     set
     {
         throw new Exception("The method or operation is not implemented.");
     }
 }

 public void Draw()
 {
     throw new Exception("The method or operation is not implemented.");
 }

 #endregion

We will now need to add a reference to the System.Drawing assembly and import the name space before we can build or we will receive an error. The next task to do is to declare a private field, _center, which will hold our center point data and then we will modify the Center property to access that field. Then we will declare the draw method as abstract so it must be overridden by any derived class.

        private Point _center;

        #region IShape Members

        /// <summary>
        /// Gets or sets the center point of the shape.
        /// </summary>
        public Point Center
        {
            get { return _center; }
            set { _center = value; }
        }

        /// <summary>
        /// All inherited classes will contain this method.
        /// The method will be used to draw it's self.
        /// </summary>
        public abstract void Draw();

        #endregion

Derived classes

Next up is to create two shape classes that will derive from the base class. The first shape we will create will be a Circle. We will add it to the root of the BusinessEntity project, and make it both derive from the BaseShape class and implement the ICircle interface. To make this class derive correctly from the BaseShape class we will need to declare a Draw() method and mark it as an override.

using System;
using Playground.ShapeMaker.BusinessEntity.BaseClasses;
using Playground.ShapeMaker.ShapeInterfaces;

namespace Playground.ShapeMaker.BusinessEntity
{
    public class Circle : BaseShape, ICircle
    {

        #region ICircle Members

        public int Diameter
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        #endregion

        /// <summary>
        /// Use this method to draw the shape
        /// </summary>
        public override void Draw()
        {
        }
    }
}

We can now create a private field _diameter and set the Diameter property to access it fully. The next shape we will add will be the Rectangle, which we will do in much the same way, except that we will create a field to hold the size data and access it from the Size property.

using System;
using System.Drawing;
using Playground.ShapeMaker.BusinessEntity.BaseClasses;
using Playground.ShapeMaker.ShapeInterfaces;

namespace Playground.ShapeMaker.BusinessEntity
{
    public class Rectangle : BaseShape, IRectangle
    {
        private Size _size;

        #region IRectangle Members

        /// <summary>
        /// Gets or sets the size of the rectangle.
        /// </summary>
        public Size Size
        {
            get { return _size;  }
            set { _size = value; }
        }

        #endregion

        /// <summary>
        /// Use this method to draw the shape
        /// </summary>
        public override void Draw()
        {
        }
    }
}

Summing up so far...

So far we have two concrete shape classes, Circle and Rectangle that derive from a base shape class. The base shape class implements the IShape interface and the concrete classes implement in turn the IShape interface as well as their respective shape interfaces.

Part 2 will show the next step, which is to build a factory class which will be used to create and return our shape objects at runtime.

Thursday, April 10, 2008 4:03:42 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | C# | Classes | Factory Pattern | Inheritance | Interfaces
 Saturday, April 05, 2008

Tonight, I stumbled upon, and then tested out, this useful article by the Wrox Team. It's all about printing WinForms in C#.

http://www.devarticles.com/c/a/C-Sharp/Printing-Using-C-sharp/

Hopefully you will find it as useful as I did. :-)

Friday, April 04, 2008 11:14:04 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | C#
 Thursday, April 03, 2008

One of my on-going projects uses a light weight client to call a web service, which runs a fairly long running process, part of which will take at minimum five minutes. Testing has proved that the request to the webserver will cause a timeout. I belive the default is about 90 seconds. There are probably many ways to circumvent this problem, but the two that i am concidering are:

  • Increase the time out settings to cover the longest anticipated duration.
  • To implement fire and forget by the client, and let the webservice spawn an additional thread to carry out the long process, returning the request almost imeadiatley.

Increasing Timeout settings

Solution

From a little web reasearch it appears that there are three settings that may be able to assist me.

  • The timeout property on the webservice proxy
  • The http-runtime setting in App.Config of the calling assembly
  • The http-runtime setting in Web.Config of the webservice.

Pros

  • Allows trapping of exceptions during the process and passing them back to the client in the form of a SoapException.

Cons

  • Process time may vary over operational lifetime of project requiring changing of configuration files, and possibly recompliling everytime the threshold is exceeded.
  • If the request times out there is no way of knowing if the process is still running.

Fire and Forget

Solution

My second solution would be to use the BackgroundWorker to spawn a new thread in the code called the from the WebService's WebMethod.

Pros

  • Allows imediate return of the WebMethod request so very little risk of time out, and therefore virtually limit less total process time.
  • Because the client needs to request whether the process has finished any way, if an exception occurs this can be handled and the status relayed back to the client at the next request.

Cons

  • Requires state of progress or completion to be stored by webservice (in database, text file, or similar).
  • Requires the calling client to keep "asking" the webservice if the task has finished. This will involve more coding and the client having to "know" that it has to keep asking for the progress and or status of completion of the task.
  • Requires extra coding to provide client with information if an exception occurs during the process.

So which is the best method to choose? Well this is probably going to sound like a bit of a cop-out, but it really does depend upon the application and how it is to be used. Each solution has it merits and its drawbacks as you can see.

For the project that I am concerned with I will no doubt use the fire and forget solution so I am not limited to time outs, as one of the processes (Archiving) will gradually take longer and longer to complete over the working life of the application, and I do not wish to be having to change the timeout and recompile frequently. I am also concerned that the timeout required couls easily surpass acceptable limits.

So how would you choose to carry out this task? Do you have any other solutions? Can you see any more advanatages or disadvantages of using either of the two solutions presented? your thoughts are welcom as always.

To be continued...

Thursday, April 03, 2008 12:24:24 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | C# | Long Running Processes | Web Services
 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

As part of the preliminary research and design process for a prospective new project at work one of the requirements will be for the application to provide a webservice that can be consumed from a third party's Java application.

So without further ado a quick .Net webservice was nocked up in C# with a single WebMethod. The WebMethod would return a formatted string containing within it the value passed in as a string parameter. The Webservice was deployed to localhost and tested using the simple webform test that is present on a local instal.

All good so far.

Next is to build a small Java web project that can consume the webservice. So having never written a Java application before, it's a quick trip to see Mr Google for a working example of how to call a webservice from Java. ( See My First Java App ) Google thankfully turned up David Hobbs' example "How to consume an ASP.NET webservice from Java via SOAP" on CodeProject. After a an hour or after nocking up a quick Java webpage with an embedded applet that will call the webservice and display the result, it should be a case of running it and seeing it work like clockwork.... After all the whole idea of a webservice is to platform unspecific, isn't it?....

Well, I shouldn't really have expected miracles, should I? After a whole afternoon of checking and double checking that the code was correct and using a free trial of ExamDiff Pro to ensure that XML that the java code was out putting was exactly what the XML that the server was expecting to receive I came to the conclusion that it must be something perculiar to our network. The XML output was identical except for the physical value of the parameter.

So at the end of the day I was at a loss. I'm not sure if it is an error in the code, or if the webservice expects different XML than what the description page offers up. Or if there is a network security issue which isn't allowing communication between the two applications. One of my .Net Windows applications calls a .Net webservice which is built in the same way as this test one perfectly, and has done for the last year! Event the third party representative was at a bit of a loss.

So I am at a bit of a loss with this one. May be a fresh look in a new week will shed some light. Who knows? If any one else has come accross this issue, and resolved or not resolved it, please post and let me know your findings!


Postscript: #1
I have just noticed on the botttom of David's CodeProject artical the following:

Notes
Some Java Virtual Machines (like the Microsoft one) only allow you to make a socket connection to the same machine that hosts the Java class files. Therefore, if you're using an applet like me, you will need to host the Java class files on the same machine where the webservice resides.

I wonder if this has anything to do with the problem... Oh well, maybe tomorrow I'll waste another fruitless afternoon trying to find out!! ;-)

Postscript: #2
Well after further investigation I haven't managed to determin the fault, but today we tried a different approach and used the "Web Service proxy" object from the Business Tier > Web Services category in the New Gallery.

We then followed the wizard and let it generate the code. The outputted code was tested and hey presto!!

So I guess this topic is closed for me now!

Monday, March 31, 2008 2:07:10 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
.Net | Java | SOAP | Web Services | XML | JDeveloper
Archive
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
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 2010
Duane Wingett
Sign In
Statistics
Total Posts: 26
This Year: 0
This Month: 0
This Week: 0
Comments: 28
Themes
Pick a theme:
All Content © 2010, Duane Wingett
DasBlog theme 'Business' created by Christoph De Baene (delarou)