Vince's Blog

Experiences and Tips on .NET Development for Business

Abstract Classes and Inheritance using C# – Part 2

In Part 1, we created a base class that contains a common property in our app, UserId. Before we move on, let’s tack on some common functions we can use throughout our app. If we bundle up some lightweight methods in a Utilities class, we can attach that to our base class as a read-only property.

We can take our new class and attach it to the base class with one line of code. We’ll need to add a constructor to our Initialize method, too.

I am sure there are detractors to this approach. I like it because I can code one reference and have my functions available in any derived class. However, I only do this with lightweight classes with methods that consume simple types, structs, enums or other lightweight classes. We’ll use the functions in this example in later articles. For now, though, we will consider this our completed super class.

Let’s go to our main class library and derive a new abstract class from the LevelOneBase class. If we’re only creating another abstract, or base, class, why not just include everything in the original base class? The reason is that, by layering abstract classes, we can propagate only the functionality required by the level we are at in our class hierarchy. As an example, our program manages tasks and tracks the result of running a series of tasks. We will create a new abstract class whose role is to manage tasks and call it TaskManager.

When you follow a new declared class by a colon and another class name, the new class inherits the other class. That means we can access the UserId property without declaring it a second time and also be able to access our utility functions. Note how when parameters are provided in the constructor, the Initialize method is called rather than setting properties right in the constructor. This is done so that logic is coded once. If we add other limitations to the container size later, we only need to update the Initialize method. This also supports the requirement that the tree must pass on initialization to the base classes.

We added a TaskCollection property to the TaskManager class to hold a collection of running tasks. One of the best parts of using async and await in C# (https://msdn.microsoft.com/en-us/library/hh191443.aspx) is that you can work, not only with class objects, but with running tasks as well. In Part 3 we will create a new method that processes these tasks and also extend our class with anonymous types as a way to manage tasks with different return types using one base class and method.

Abstract Classes and Inheritance using C# – Part 1

On a recent project, I tried to make better use of inheritance to simplify coding and improve the supportability of the end product. In the C# Programming Guide, inheritance is defined as a technique that “enables you to create new classes that reuse, extend, and modify the behavior that is defined in other classes.” In my case, I was seeking out ways to code a piece of business logic once and then share it using base classes. Sometimes, the base class is not even in the same assembly as the derived class let alone in the same namespace. I also try and use access modifiers to only show functionality on a need to know basis. By only showing the meaningful set of methods and properties, it makes the next programmers job easier as the intended way to use the class is clear. It’s actually easier to show than describe, so let’s get started.

Let’s start with our base class or “super class”. This is the class that contains the properties and methods used by its offspring or derived classes. An easy property to picture being shared is a UserId property. Let’s say that most, if not all work being done in the application needs to know who the user is. This might be for security, personalization, or to have on hand for interacting with data stores. Here is our base class with the UserId property.

There are a few things to know about and a few problems with our class. As the namespace suggests, the base class will actually be contained in a different assembly than our derived class. The C# language only supports two access modifier types for classes defined at the namespace level, public and internal. The default is internal, so our new class won’t be visible outside of the NewAssembly.dll library. In addition, the base class isn’t useful as a stand alone class. This is easy to fix by using the “pubic” access modifier and “abstract” keyword. This will make the base class visible outside the assembly, but it can only be inherited, not instantiated on its own.

Now, let’s look at the UserId property. Since within a class the default access modifier is “private”, the property won’t be visible outside of the class. We would like it visible to any derived class, but not outside of the class hierarchy. In addition, we want to set the value of the property when the class is instantiated, but not allow it to be changed afterwards. To accomplish this, we can use the “protected” access modifier and change the set action to private.

This creates a new problem. How should we set the value of the UserId property? For reasons I can’t fully cover here, I have become a fan of providing a default parameterless constructor, a loaded constructor with all required parameter and an initialization method to set base values. The parameterless constructor and initialization method need to both have the same access modifier. If they were both private, it would work but the parameterless constructor is really just a placeholder as it is inaccessible outside of the class. The loaded constructor can use the same modifier or provide even more access, but not less access.

Let’s take another look at the access modifiers we’ve chosen. The base class has a “public” modifier since anything less makes the base class useless outside of the assembly. However, the constructors are “protected”. This is because initialization of the base class needs to be managed by the derived class. The derived class will likely contain a public initializer, but the base class initializer should only be visible within the class hierarchy. It’s reasonable to let users of the derived class know whether the class is initialized and what the UserId value is. Therefor, these are both public. In the next article, we’ll inherit from our new base class.

Good articles to support layered architecture with Silverlight

I am working on a data warehouse administration portal using Silverlight with the MVVM pattern. It was hard to find an end to end example with associated sample code. However, I found the following two articles, when mashed, provide a good overview. I used the first article by John Papa to build the data service using WCF. I used the second article by Shawn Wildermuth to design the front end.

John Papa: http://msdn.microsoft.com/en-us/magazine/cc700340.aspx (this article has since been removed – vp)

Shawn Wildermuth: http://msdn.microsoft.com/en-us/magazine/dd458800.aspx

SQL Server default data folder and VSTS database project creation

I upgraded my Visual Studio 2008 Professional edition to the more robust Visual Studio Team System (VSTS) Database Edition. My goal is to have a better toolset for managing database versioning than SSMS, and to support the inclusion of both database and .NET projects in the same solution.

After installing, I attempted to create a database project using the SQL Server 2005 template, both with and without the wizard walk-through. This resulted in a general error message, “Failed to create database”. There was no additional information in the Event Log and no log file was created in the project file.

To solve this, I used the SQL Server 2005 profiler tool. Visual Studio requires a local install of SQL Server that it uses to validate schema. When a project is created, Visual Studio attempts to create a database that matches the project name if one does not already exist in the designated local instance. By examing the profiler output from the database creation attempt, I was able to see that Visual Studio was attempting to create physical database files in directories that were no longer valid. I had moved all of my database files from Z:\Data\MSSQL to Z:\Mssql\Data to match the convention of a client. However, after deleting the first directory, I had not changed the default data directory setting in SQL Server to the new location. When I created databases using the SSMS interface, SQL Server allows me to manually replace the invalid setting with a valid one. Visual Studio, however, relies on this setting to determine file placement. When I corrected the setting SQL Server’s database options, the Visual Studio project creation completed successfully.

Powered by WordPress & Theme by Anders Norén