.Net Wanderings RSS 2.0
 Monday, April 07, 2008

I'm really getting tired of waiting for computers to do things; boot, shutdown, open Visual Studio, build. I feel like I spend more time waiting for the computer to do something then actually getting work done and this is very frustrating. I like my laptop and unfortunately it's not dual core, but I've decided that for the amount of mobility that I need it can still handle the job. What I do what to do is build a new desktop development box that I can use when working in the office since this is where I do most of my work, outside of the day job anyways. I've gotten a bit out of touch with the hardware world lately so I was hoping to solicit some feedback in a few areas. Here is a list of the general specs I've laid out.

 

Quad Core Processor – I realize that this is still a bit vague since some argue that a dual core with a faster speed is better that a slower quad core, but I hope to get the fastest quad core processor for a reasonable price when I make the purchase.

Motherboard – This is where I've gotten a bit rusty. Does anyone have any suggestions on brands and specs that I want to look for?

Vista Ultimate 64 bit – Yeah, Yeah don't do it, Vista sucks. I'm going to do it anyways.

4GB of RAM – Anything important here besides speed and response time?

16-30GB Solid State Hard Drive – This one I think is the sweet spot. The last moving part on the computer is the hard drive and common sense says that means it's the real bottleneck. I hope to get a small solid state hd that will hold the OS, VS2008, and maybe Office depending on price vs size. My one issue here is I haven't seen any 3.5 inch solid state drives.

Large Secondary Hard Drive – A regular SATA hard drive to handle everything else that isn't used all the time. I'm thinking a WD Raptor for this.

Video Card(s) – Yet again I'm going to need to do some research here or get some feedback. What specs do I need to look for here?

2 X 22 inch Widescreen Monitors – I haven't decided on anything specifics here, I just know I want 2 that are exactly the same so they are at the same level.

Case – A really, really quiet case. This is going to involve research too.

 

Any feedback that anyone has would be great.

 

Monday, April 07, 2008 8:01:36 PM (Central Standard Time, UTC-06:00)  #    Comments [3] - Trackback
Development | Hardware
 Sunday, March 16, 2008

    Well its official The Gifford has turned me into a code coverage addict. After he helped me through writing my first unit test using NUnit the concept slowly started sinking in and I'm now addicted to code coverage. Writing NUnit tests is so easy that I don't understand why everyone won't do it, which is causing me to get a bit frustrated with people as it gives me the impression that they just don't care. I can't remember the number of times that I have gotten rather pissed because someone has changed my code and broken functionality and in some cases I've even broken my own code when I've had to go in and make changes after not looking at it for some time. Unit testing can minimize these hair pulling moments by giving you more confidence that what was supposed to be happening before you touched the code still happens after you touched it. If someone is in muddling around in your code and breaks something, you'll know immediately when they check in and the test doesn't pass on the build server. It all comes down to code quality and I have begun to notice recently that code quality everywhere sucks.

    If you're not using unit testing of some sort then I think it just boils down to pure ignorance. Either you see the value of unit tests, but don't know how to write them and are too lazy to exert the effort to learn how, or you are just too ignorant to see the value of them. I fell into the first group. I've always seen how they could be helpful, but never took the time to learn how to do them. In the last couple weeks I've been really thinking about code quality with the product that I am building with a couple partners. We decided to build this product because we had gotten stuck working with another product that we thought had many problems and was a pain to work with. I realized that we were starting to walk down the same path, rushing to get a beta out, sacrificing design and architecture for deadlines. There are plenty of poor applications on the market and I don't want to be contributing to that. I want to produce a quality product or nothing at all because in the long run if we produce a poor quality product then we get stuck supporting that poor quality and our customers are stuck working with it. While assessing quality I kept coming back to our lack of unit testing and the fact that things kept breaking that worked fine the day before. This motivated me to overhaul the build server so that it runs NUnit tests automatically and then uses NCover to provide statistics on the code that is covered by unit tests and the code that is not covered. Then to take it one step further I built a screensaver that runs on the monitor of the build server that displays the overall percent of code coverage from the project in bright flashing red while it is under the coverage goal. (Currently FloFactory is at 9.5% code coverage with a coverage goal of 50%.) I look forward to the day that that text turns green to indicate that we have met our code coverage goal (and then I'll raise the goal).

    I'm sure plenty of people would argue about the value of unit testing, pointing out various short coming with unit testing which I am sure are all valid in certain scenarios, but if you're following a tiered structure for your application, keep your logic out of the UI and keep your data access separate, then you should have an entire service layer that can be unit tested. Does having unit tests mean your code is perfect, of course not. It's not a silver bullet for quality but it is one tool to provide a bit more certainty about an application.

    Where I am really struggling is motivating others to improve their code quality, understanding the importance of testing and getting them to write even one unit test. I realize that unit testing can't cover your entire application, but it's a start and if you start thinking about how you structure your application you'll starting seeing better ways to design things so that you can properly test them using such things as mock objects and inversion of control containers. The Gifford told me once that he goes by the statement "You don't have write unit tests, but don't break mine." Whereas I like this statement, I don't think it motives any one to write a single unit test, so I'm adding onto this by trying to make the statistics more visible. Hopefully if someone checks in code that lowers the overall coverage percent, that they can see very clearly on the build server screensaver, they may feel more motivated to raise that number.

    As for myself, I'm going to keep digging into ways to increase quality so that the final product is stable and worth using. One last thing to point out is that if you plan to get started unit testing and are going to use NUnit then I would suggest picking up a copy of Resharper. It allows you to run your NUnit tests extremely easily from Visual Studio taking some of the headaches out of writing them.

Sunday, March 16, 2008 6:39:55 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Development | NUnit | Testing | Unit Testing
 Sunday, January 20, 2008

    So far I have went over how to create a basic workflow activity that evaluates a regular expression against a string and I have also covered creating the validation class for the activity. The next thing I want to cover are some basics to enhancing the designer experience of the workflow activity allowing you to override the default visual display in the designer for a custom activity. Based on the default designer class our RegEx activity appears as follows:

    

    The first thing that needs to be done is to add a new class to the project called RegExDesigner.cs.

    

 

    Next we need to make our new class inherit from the ActivityDesigner class. To do this we will also need to import the namespace System.Workflow.ComponentModel.Design, which means your code should now appear as follows:

    using System.Workflow.ComponentModel.Design;

 

namespace FloFactory.Activities.Util.Logic

{

    public class RegExDesigner : ActivityDesigner

    {

    }

}

 

 

    There are a lot of functions that you can override, but the main function that we are going to work with is the Initialize function which will allow us to override the appearance of our activity in the designer. This first thing that I am going to do is add a nice image to the activity. Assuming you already have an image that you want to use as a resource in your project you add the image to the activity's design view by doing the following:

 

protected override void Initialize(System.Workflow.ComponentModel.Activity activity)

{

base.Initialize(activity);

Bitmap WorkFlowImage = Properties.Resources.workflow;

 

Image = WorkFlowImage;

 

}

 

    The other thing I would like to do is change the text that appears in the activity. This will be the default text that shows up until the user of our activity sets the name property. This is easily done by setting the Text property in the Initialize function. After doing this the code should appear as follows:

 

    protected override void Initialize(System.Workflow.ComponentModel.Activity activity)

{

base.Initialize(activity);

Bitmap WorkFlowImage = Properties.Resources.workflow;

 

Image = WorkFlowImage;

 

//Set the Text That appears

Text = "FloFactory RegEx";

 

}

 

 

    Now we need to associate the designer class with our activity. We do this by going to the top of the RegEx.cs class and add the following attribute:

    [Designer(typeof(RegExDesigner), typeof(IDesigner))]

    public partial class RegEx: BaseActivity

    {

        …

}

 

 

 

    After adding this code to the Initialize function and adding the attribute if we now look at the RegEx activity we will see that our image has replaced the default image that appeared when the original designer class was applied to the RegEx activity. Also, the default text that was defined appears in the center of the activity.

 

 

    As you can see we have easily modified the image and the text that appears in the designer for our RegEx activity. In a future post I will cover modifying the appearance of the activity by changing its size and colors so as to create a more custom look and feel for the activity.

 

    

 

 

 

Sunday, January 20, 2008 8:38:13 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
.Net 3.0 | Development | Windows Workflow
 Tuesday, January 01, 2008

    Well lately I have been using Resharper from JetBrains which is an amazing Visual Studio Add in that adds an extensive amount of new features and shortcuts. It has greatly increased my productivity and if you're not using it then you should at least download the 30 day trial and test it out. (Greg this means you. Tell Matt I said he should buy it for you.) I especially like the file structure explorer that allows me to organize functions and properties in a class by dragging them around instead of needing to copy and paste them. This is very helpful when organizing your classes into regions. Also, if you've ever had a giant solution where it begins to be difficult to find files you'll appreciate the file search that allows you to start typing a filename and get a filtered list of files. It definitely can be a bit overwhelming with all the shortcuts it adds to Visual Studio so in order to make looking up the shortcuts easier I created this basic VS2005 add in that displays the Resharper cheat sheet on the screen. After installing the Recheater Add in you can display the cheat sheet by hitting CTRL-ALT-SHIFT-H and close it down by hitting the ESC key. To change the shortcut key simply modify the config file located under My Documents\Visual Studio 2005\Addins\RecheaterAddin. It's a pretty basic application, but feel free to download Recheater and post a comment if you find any bugs or want to suggest an enhancement.

Tuesday, January 01, 2008 11:09:57 AM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Development | Resharper | Visual Studio
 Friday, December 28, 2007

    I'm my last posting I walked through how to create a custom regex activity in Windows Workflow and I thought a good next step would be to give a short example of how you would add validation to this custom activity. In this particular instance we want to make the InputString property and the RegExpression property required in order for the workflow designer to consider the workflow that is being built a valid workflow. The first thing that needs to be done is to add a class to the project called RegExValidator.cs.

 

    The next thing that needs to be done to the new class is to add using System.Workflow.ComponentModel.Compiler to the top of the class and make it inherit from ActivityValidator. The one function that we need to override is the validate function. The validate function takes in a ValidationManager and an object. The object is what we will be using as this is the instance of our activity that we will be validating. The function returns a ValidationErrorCollection which is simply a collection of error messages that we will send back after validating the activity. In the override for this function we check that both the InputString and the RegExpression properties are not null or empty. If they are we add a corresponding error message to the collection. Because the error is associated with a property we provide the property name as the last parameter in the constructor for the ValidationError object so that the designer can associate the error message with the apporpriate property.

 

public class RegExValidator : ActivityValidator

{

public override ValidationErrorCollection Validate(ValidationManager manager, object obj)

{

RegEx myRegEx = obj as RegEx;

ValidationErrorCollection myErrors = new ValidationErrorCollection();

 

if (myRegEx != null && myRegEx.Parent != null)

{

 

 

if (myRegEx.InputString == null || myRegEx.InputString.Equals(String.Empty))

{

myErrors.Add(new ValidationError("InputString is required.", 101, false, "InputString"));

}

 

if (myRegEx.RegExpression == null || myRegEx.RegExpression.Equals((String.Empty)))

{

myErrors.Add(new ValidationError("RegExpression is required.", 102, false, "RegExpression"));

}

}

 

return myErrors;

}

}

    That is all we need to do for the validator class. The last thing we need to do is associate our validator with the activity. To do this we add the same using statement to our RegEx.cs activity (using System.Workflow.ComponentModel.Compiler) and we add an attribute to the top of the class.

     [ActivityValidator(typeof(RegExValidator))]

    public partial class RegEx: BaseActivity

    {

    …

    }

    That's it. If we now use the original sample workflow I created and blank out the InputString and RegExpression properties we will get several indications that there are errors. First in the designer it will be indicated directly on the activity.

    In the properties window it will also indicate each individual property that has an error.

    Finally the build will error and the error messages will be provided in the error window.

 

    That's all I have to say about validation. Obviously the validation can be much more complicated than just checking if the property has been provided, but this example hopefully provides a basic idea of how to get things going. Feel free to post a comment if you found this helpful and would like for me to dedicate more postings to the wonderful world of workflow. Now I'm off to go find a life since it appears that I am blogging on a Friday night. Unfortunately that's not something you can Google for!

Friday, December 28, 2007 8:54:49 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
.Net 3.0 | Development | Windows Workflow
 Wednesday, December 26, 2007

    While having lunch today at Old Chicago with Nick we began discussing Windows Workflow a bit and I started to realize that even though I have been pounding away on a project for six months that is highly dependent on WF I have yet to write a single blog post on the topic. I found the need today to work on an activity that simply applies a regular expression against a string and returns the value that it finds. Since this is a fairly basic activity I thought I would go ahead and blog about the process of creating it.

First off you need to create a new activity:

 

Visual Studio 2008 will create the skeleton of an activity for us that inherits from SequenceActivity. For my purposes I need to have it inherit from Activity so I will go ahead and change this. The next thing we need to do is to define a dependency property for our input string. To do this we do the following

#region "Dependency Properties"

 

public static DependencyProperty InputStringProperty = DependencyProperty.Register("InputString", typeof(String), typeof(RegEx));

 

#endregion

What we are doing here is registering a dependency property called InputStringProperty that is bound to the property InputString (which we will be creating in a second), the property of InputString is of type string and the owner of InputString (our activity) is of type RegEx. Now we need to define our property InputString.

 

     #region "Properties"

 

public string InputString

{

get { return ((String)(base.GetValue(RegEx.InputStringProperty))); }

set { base.SetValue(RegEx.InputStringProperty, value); }

}

 

#endregion

The layout of this property is fairly similar to what you should be useto, but instead of getting and setting from a private member variable you instead set and get from the dependency property. Piece of cake right? The next thing we are going to do is define our output parameter the same way. The only thing that we are going to do differently with this property is to put an attribute on it of readonly. This will prevent the user from binding this property to something since the user should only be binding the properties on other activities to this property.

 

public static DependencyProperty OutputStringProperty = DependencyProperty.Register("OutputString", typeof(String), typeof(RegEx));

 

     [ReadOnly(true)]

public string OutputString

{

get { return ((String)(base.GetValue(RegEx.OutputStringProperty))); }

set { base.SetValue(RegEx.OutputStringProperty, value); }

}

 

 

Though we are not complete yet, if you build this activity and drop it onto a test workflow you will see the following in your Visual Studio Properties Window. We have a property call input string that is bindable and a property called OutputString that is readonly.

 

 

The next things we need to do is to declare a property that will hold our regular expression for the user of our activity to input. The will not be a dependency property, but a standard property as it will not need the ability for binding.

     private string _regexpression;

     public string RegExpression

     {

get { return _regexpression; }

set { _regexpression = value;}

     }

 

If you now drop this activity onto a test workflow you will see the following on the properties window.

 

 

We're almost done and all that is left to do is to implement the Execute method of our activity which will actually evaluate our regular expression against the input string. First off make sure you put using System.Text.RegularExpressions at the top of the class as we will obviously be using the .Net RegEx features. Then we just have the following function left.

 

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

{

Regex myRegEx = new Regex(RegExpression, RegexOptions.IgnoreCase);

OutputString = myRegEx.Match(InputString).Value;

return ActivityExecutionStatus.Closed;

}

 

The Exceute function is the meat of the activity where our processing actually happens. We first create a new RegEx object using our RegExpression property and in this case we are passing the option to ignore case. We then evaluate the regular expression and place the value into our OutputString property. Finally we return with a closed status and that's it. Just to test it out I put together a basic workflow that consists of my activity with the InputString property set to "my email address is testperson@test.com and of course it isn't a real email" and the RegExpression property set to "\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" which should pull out the email address. I then used a basic code activity to output the email address to the console.

 

 

There you have it, a workflow activity that evaluates a regular expression against a string. If an email address had not been found then a blank line would have been written out to the console, but in our case we got testpersion@test.com. Obviously in a more practical scenario you would not type the string directly into the InputString property, but instead you would bind that property to the string property on an activity earlier in the workflow, but you get the idea. That's it for now folks. If you enjoyed this posting or found it helpful and would like to see me post more on WF feel free to post a comment.

Wednesday, December 26, 2007 9:39:10 PM (Central Standard Time, UTC-06:00)  #    Comments [3] - Trackback
.Net 3.0 | Development | Windows Workflow
 Sunday, November 25, 2007

The other day I ran into the need to access a nested property on an object with the actual name and path to the property stored in a string variable. For example I had a mail object and wanted to access "From.DisplayName" which was stored in a string. If I was access just the from I could have used something like this:

using System.Reflection;

PropertyInfo[] pi = myObject.GetType().GetProperties();

foreach (PropertyInfo item in pi)

{

if (item.Name = "From")

{

object o = item.GetValue(myObject, null);

}

}

 

In this example myObject is the mail object and we first get the type of it, and then get an array of the properties for that type. Finally we find the From property and get the value for that property on our object.

Unfortunately this doesn't work for nested properties and I could not find a built in way to do it so I built a recursive function to handle getting the property for me and returning it. I then packaged it into a handy .Net 3.5 extension method. Let me know if you know of a built in method to get a nested property, otherwise feel free to using the extension method I put together, though it probably needs a bit of refactoring before you put it into production.

namespace Common.ExtensionMethods

{

public static class TypeExtensionMethods

{

public static object GetNestedProperty(this Type t, Object o, String Property)

{

object myObject = null;

PropertyInfo[] pi = t.GetProperties();

 

 

 

if (Property.IndexOf(".") != -1)

{

 

foreach (PropertyInfo item in pi)

{

 

if (item.Name == Property.Substring(0, Property.IndexOf(".")))

{

object tmpObj = item.GetValue(o, null);

 

myObject = tmpObj.GetType().GetNestedProperty(tmpObj, Property.Substring(Property.IndexOf(".") + 1));

 

}

 

}

 

}

else

{

foreach (PropertyInfo item in pi)

{

if (item.Name == Property)

{

myObject = item.GetValue(o, null);

}

 

}

}

 

return myObject;

 

}

}

}

Sunday, November 25, 2007 10:03:26 AM (Central Standard Time, UTC-06:00)  #    Comments [1] - Trackback
Development | Extension Methods
 Sunday, October 28, 2007

    I originally thought of this idea while at Professional Edge. We had a client that wanted to build a portal and resell the functionality it provided to other companies. The main functionality and content for the site would be the same for each customer, but styles, images, and logos would change based on each company allowing the company to portray the website as their own. Professional Edge closed before the project was signed off on so I never got the chance to tackle a solution, but every once in awhile the concepts pops back into my head. I am sure this is a fairly common scenario and most likely what I have done here has been done plenty of times before, but I thought I would attempt to put together a proof of concept. My initial plan was to dynamically generate the App_Themes data based on information from the database. Using this method the developer would build the site with the look and feel defined via css tags and skin ids. The end corporate user would then have a user interface to define their custom styles and images that applied to each css tag and skin id. If the user did not define a tag then the website would simple use a default theme that the developer defined.

    To do all this I have utilized the functionality of virtual path providers. A virtual path provider allows you to essentially take over when ASP.NET is looking for the file to server to the user. In my particular case it is for .css and .skin files, so that whenever a request comes in for one of these files it is instead dynamically built based on data from the database. Originally I had planned to associate a particular theme name with each portal's customizations. For example on the pre-init the theme would be dynamically set based on some type of user information, either a login account, or possibly the web address used to access the site. Basically any type of information that establishes the unique portal that the visitor is attempting to reach. Unfortunately this plan won't work. Apparently ASP.NET requires the actual physical files for a theme to exist or else it will throw an error. This was a bit of a disappointment to me as I had hoped to parse the theme name in the virtual path provider to know what dynamic data to load. Since the path is the only data passed into the virtual path provider it is the easiest and cleanest way to know what data to load. If the file trying to be loaded is ThemeABC.css I could load the styles for portal ABC and if the file trying to be loaded was ThemeXYZ.css then I could have loaded the styles for portal XYZ.

    Even though this method didn't work I was able to development another method that does. I have created the file structure for the Default theme with dummy files, including Default.css and Default.skin. Every portal will essentially be using this theme as far as ASP.NET is concerned, but when a request comes in for Default.css or Default.skin I pass back a dynamically generated file. The decision for what styles and ids need to be loaded is based on a cookie that is set in the pre-init. This cookie is then read in the in the Open function of the virtual file class for the virtual path provider and based on what the cookie says a decision is made as to what styles are handed back to the client.

    In the attached sample code there are two different themes that can be accessed, blue and red. Setting the cookie is handled in the Default.aspx's OnPreInit. Since this is a proof of concept the actually string is hard coded, but it could just as easily read the address that the request came in on, a user login, or user setting. Then in the virtual path provider I handle any of the requests that come in for APP_THEME/DEFAULT/. Finally in the virtual file class I read the theme name from the cookie and hand back the proper page. Since this is a proof of concept I have simply hardcoded a few values to hand back, but you could easily query the database and hand back a much more dynamically generated file.

    At this point hopefully you can see the numerous possibilities this allows for. If all the ok buttons on the entire site are defined with a skin id of btnOk then you could allow the user to upload the image they want for their ok buttons and instantly all the ok buttons on the site reflect what the user has defined. If you consistently use your css tags within you site then the user could easily define custom colors, fonts, etc. for each one. This would allow the user to very easily customize the site to the look and feel that represents their company without having a developer make any changes.

    Feel free to check out the sample code at the link below and make any comments or suggestions. Since it is just a proof of concept it is a little rough and not that elegant, but it displays the point.

Download the source code to the proof of concept. (VS2008 required)

    

    

Sunday, October 28, 2007 7:03:34 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
ASP.NET | Development

Navigation
Archive
<August 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456
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 2008
David A. Osborn
Sign In
Statistics
Total Posts: 53
This Year: 10
This Month: 0
This Week: 0
Comments: 30
Themes
Pick a theme:
All Content © 2008, David A. Osborn
DasBlog theme 'Business' created by Christoph De Baene (delarou)