Tuesday, January 29, 2013

Configure RavenDB with IIS

With the latest release of RavenDB 2.0, configuring for IIS has changed a bit. I've put together a quick step by step on how to get RavenDB running locally within IIS.

 Download the latest RavenDB at http://ravendb.net/download

Create a site within IIS and setup the bindings accordingly.  I used port 8989 because I had something else using port 8080, but you can use whatever works for you.  Unzip the Raven download and copy the contents into your new site path.  I created a folder like c:\inetpub\wwwroot\raven.  Then copied the unzipped contents into that folder.  Point your site to the Web folder within the unzipped contents in the folder you created to host the site.

Things to make sure are installed and configured:
   1) Make sure you have Windows Authentication installed and enabled.  If not, simply go to your control panel, open up the Programs section (This may be different depending on version of windows) and select the Turn On/Off Windows Features.  Navigate to your IIS section, expand it, expand World Wide Web Services and then Security.  Make sure Windows Authentication is checked and click OK.  Next go to your IIS site you created and click on the Authentication link.  Right click on Windows Authentication and enable it.

2) Make sure your App Pool for your RavenDB site is using an administrator account, located in the Advanced Settings under Identity (I created an admin account called RavenDB and assigned it)

3) Make sure your site's Physical Credentials located in Advanced Bindings are using the same admin account.  This is important so Raven has write access to create the databases it needs.

4) Make sure your App Pool for your RavenDB is using Integrated pipeline and running .Net 4.0


That's pretty much it, you should be able to hit the DB Manager and work as normal.  Of course there are more security settings you can apply and group security.  This post will get you up and running locally so you can test your application against RavenDB locally within a development environment.  For more security options, see http://ravendb.net/docs/2.0/server/authentication

Wednesday, January 25, 2012

FubuMVC Conventional Design List View

Coming from Asp.Net MVC I was so used to the structure expected, for example all controllers had to end in “Controller” and your controllers were separate from the Views etc.  Nothing wrong with this design, but coming into Fubu and having so much freedom to place files how ever you want them was a bit daunting at first.  What I want to cover over my next blog posts are the following conventional ways FubuMVC makes structuring your project easier, and how it does a lot of the heavy work for you out of the box.  This post assumes you have something similar to the configuration as this.

  1) Conventional List Views (this post)
  2) Conventional Create Views
  3) Conventional Edit Views
 

I chose these as they are the most commonly structured tree within a web application.  So this looks something like:

root
   - EntityFolder
       - List.spark
       - Edit.spark
       - Create.spark (or New.spark)

This is pretty common so it makes sense to target the 80% audience and hopefully someone gets something out of this.  To start off I’m assuming you use the following structure and that your entities use an interface like so:

public interface IEntity
{
    int Id { get; set; }
}


Note: Id can be int or Guid, doesn’t matter



Now going back to my Asp.Net experience, wanting a list view to render, the most common style was creating a Controller and then an ActionResult method named Index.  I could do this same thing in Fubu, however if my style of entity design is always going to be Create, Edit, and List then why not let Fubu perform this task for me conventionally.  To get started we will need to build up our convention, lets add a class and call it ListEntity<T> so that it accepts any of our entity classes.  This guy will be responsible for getting a collection of our objects and returning them.



public class ListEntity<TEntity, TList>

where TEntity: class, IEntity

where TList : IEntityList<TEntity>, new()

{
    private readonly IRepository _repository;  	
  	
    public ListEntity(IRepository repository)  	
    {  	
          _repository = repository;	  	
    } 
	  	
    public TList<T> Get(EntityList<TEntity> items)  	
    {
       return new TList<T>() {Items = _repository.All<TEntity>()};
    }	
}


Now lets create our Model that we will use to bind our list



public class EntityList<T> : IEntityList<T> where T : IEntity	  	
{  	
     public IEnumerable<T> Items { get; set; } 	  	
}


You see I’m using an IEntityList, that is nothing more than an interface requiring an IEnumerable<T> Items.  Now what we have here is the conventional piece that will be responsible for delivering EntityList<T> to our Model.  We need a class that takes in IActionSource and will be responsible for ensuring our convention is triggered which will call our ListEntity Get method.



public class ListEntityActionSource : IActionSource  	
{	  	
     private static readonly string MethodName = ReflectionHelper.GetMethod<ListEntity<IEntity, EntityList<IEntity>>>(a => a.Get(null)).Name;	  	
	  	
     public static MethodInfo GetExecuteMethod(Type action)  	
     {  	
         return action.GetMethod(MethodName);	  	
     }
	  	
     public IEnumerable<ActionCall> FindActions(TypePool types)
     {
	 return types.TypesMatching(type => type.IsConcreteTypeOf<IEntity>())
	  	.Select(t =>
	  	 {
	  	     var action = typeof(ListEntity<,>).MakeGenericType(t, getListType(t);
	  	     return new ActionCall(action, GetExecuteMethod(action));
	  	  });

}

 

private Type getListType(Type entity)
     {
            return _container
                .Model
                .DefaultTypeFor(typeof(IEntityList<>).MakeGenericType(entity));
     }

}


And now we need to generate a way to register this with fubu as well as set our route up



public class ListEntityEndpoints : IFubuRegistryExtension	  	
{	  	
     public static string ToRoutePattern(Type entityType)  	
     {	  	
        return "{0}/list".ToFormat(entityType.Name.ToLower());	  	
     }	  	
	  	
     public void Configure(FubuRegistry registry)	  	
     {	  	
         registry.Actions.FindWith(new ListEntityActionSource());	  	
         registry.ApplyConvention(new LambdaConfigurationAction(graph => graph.Actions().Where(x => x.HandlerType.Closes(typeof(ListEntity<,>))).Each(ModifyChain)));	  	
     }	  	
	  	
     public static void ModifyChain(ActionCall action)	  	
     {	  	
         var chain = action.ParentChain();  	
         var pattern = ToRoutePattern(action.HandlerType.GetGenericArguments()[0]);
         chain.Route = new RouteDefinition(pattern);	  	
         chain.Route.AddHttpMethodConstraint(action.Method.Name.ToUpper());	  	
     }	  	
}


Then to register your ListEntityEndpoints, simply import it into your FubuRegistry like so:



public class MyFubuRegistry : FubuRegistry
{
    ... 
    Import<ListEntityEndpoints>();
    
    ...
}


And now we add into our Registry a section informing Structuremap how to use our IEntityList types, since we are using a generic we have to implement a closing type otherwise spark may have issues:



public class WebRegistry : Registry
{
    public WebRegistry()
    {
        Scan(x =>
                 {
                     x.TheCallingAssembly();
                     x.WithDefaultConventions();
                     x.ConnectImplementationsToTypesClosing(typeof (IEntityList<>));
                 });
    }
}


This is so awesome how this works, now that I have configured my convention, all I have to do from now on for all my entities that I want a list view is to use IEntityList<T> or I can create a model that inherits EntityList<MyEntityClass> (EntityList inherits IEntityList) for the model of my spark view and voilĂ ! This works for your simplest case.  If you need additional behaviors for your list, this of course would need additional behaviors added.  But for the most part, if you need a view that renders a basic list of data then this covers your common list scenarios.  Fubu will wire this up automatically and you now have a list view, you do not require another Endpoint (Or Controller for Asp.Net MVC guys) from here on out.  Keep in mind this adds a List to all of your IEntity types (person/list, address/list, etc), the only difference is only entities that are wired up to a View will actually be chained to a View endpoint.



 



I tried pulling parts out of my codebase and we all know its difficult to get what is needed for a blog post only and exclude the rest of the sections, so if you have some issues getting started with this don’t hesitate to contact me gary.l.coxjr AT gmail.com



 



Happy Coding!

Monday, January 23, 2012

Getting Started with FubuMVC

With FubuMVC getting closer and closer to version 1.0, more and more developers are adopting it for its conventional design and the ability to control all aspects of its behavior.  I started using FubuMVC 4 months ago and ran into many road blocks as there wasn’t (And currently as of this post “isn’t”) very much documentation on how to get started and what you can do.  I would like to spend the next few weeks writing up posts on how to first get Fubu up and running, then how to use its conventional power and the underlying magic within.  I say magic because it is what it is, the framework is simply brilliant and I want to demonstrate it’s power little by little over each post.  There are currently two ways you can configure FubuMVC for a new project, one would be to download the Nuget package “FubuMVC”

image

 

This is basically the Starter package which will load all the references and get FubuMVC configured and Setup for you.  Im not going to cover that route as it’s pretty straight forward and easy for anyone to get started.  What I want to demonstrate is the manual approach to configuring FubuMVC.  For me its always better to get your hands dirty and really learn how to use your tools and what they truly do under the hood.  So lets begin.

Create a new ASP.NET Web project (Empty).

image

Next, right click on your references and select Manage NuGet packages, you should get the same screen as the NuGet image above.  Type in FubuMVC in the search and choose FubuMVC.References and FubuMVC.Spark.  This will load all the required references you need to get Fubu up and running.  Lets assume I created my project as MyFubu.  First step we need is to get Fubu bootstrapped and registered.  Create a class in your web project, for me I might call it MyFubuApplication keeping it named after my project.

public class MyFubuApplication : IApplicationSource
{
    public FubuApplication BuildApplication()
    {
        return FubuApplication
            .For<MyFubuRegistry>()
            .StructureMap(WebBootstrapper.BuildContainer);
    }
}







Now we need to create our registry class and our web bootstrap class.



public class MyFubuRegistry : FubuRegistry
{
    public MyFubuRegistry()
    {
        IncludeDiagnostics(true);
        Applies
            .ToThisAssembly();
        Actions
            .IncludeTypesNamed(name => name.ToLower().EndsWith("endpoint"));
        
        Routes
            .HomeIs<MyHomeEndpoint>(e => e.Index(null))
            .IgnoreControllerNamesEntirely();
        Views
            .TryToAttachWithDefaultConventions();
        this.UseSpark();
    }
}


and for our bootstrap class, this is where you educate Structuremap on where your Registry classes are:



public static class WebBootstrapper
{
    public static IContainer BuildContainer()
    {
        ObjectFactory.Initialize(x =>
        {
            x.AddRegistry<WebRegistry>();
        });
        return ObjectFactory.Container;
    }
}
public class WebRegistry : Registry
{
    public WebRegistry()
    {
        Scan(x =>
        {
            x.TheCallingAssembly();
            x.WithDefaultConventions();
        });
    }
}


As you can see in the FubuRegistry I set the route of HomeIs<MyHomeEndpoint>, what this is telling fubu is when the site loads to direct the user to the default landing page which is in MyHomeEndpoint.Index.  That class would look something like this:



public class MyHomeEndpoint
{
    public HomeViewModel Index(HomeViewModel input)
    {
        return input;
    }
}
public class HomeViewModel
{
    public string HelloWorld
    {
        get { return "Hello World";}
    }
}


Now all I would need is a spark file that uses my HomeViewModel as its model and FubuMVC will build a route to this view which would look something like MyHomeEndpoint/Index. Now this looks a bit tacky having the word endpoint in your url. Not a problem, Fubu allows you to control the way your routes display. To override the way FubuMVC creates your routes simply create a class that inherits IUrlPolicy, something like the following:



public class EndpointUrlPolicy : IUrlPolicy
{
    public bool Matches(ActionCall call)
    {
        return call.HandlerType.Name.EndsWith("Endpoint");
    }
    public IRouteDefinition Build(ActionCall call)
    {
        var routeDefinition = call.ToRouteDefinition();
        routeDefinition.Append(call.HandlerType.Namespace.Replace(GetType().Namespace + ".", string.Empty).ToLower());
        routeDefinition.Append(call.HandlerType.Name.Replace("Endpoint", string.Empty).ToLower());
        return routeDefinition;
    }
}


And register this in your FubuRegistry class



Routes.UrlPolicy<EndpointUrlPolicy>();


And that’s it, your new route policy is in effect and now our url is rendered as /MyHome/Index.  Further customization could be performed to remove the Index as well if desired.



This covers the setting up of FubuMVC portion, to make sure your routes are wired up correctly, run your application and go to localhost:YOURPORT/_fubu to see the advanced diagnostics.  Click on the Behavior Chains link and check that your routes (Mine would be MyHome/Index) are present.  You can also click on the Behavior chain link next to the route to see how Fubu wired it up.  The Advanced Diagnostics will quickly become your closest friend when working with Fubu as it informs you of any chains that are not correctly routed and helps you understand why they are not working as you desired them too.



This about sums it up for getting started, go check out FubuMVC for yourself and see what you think about it.



The FubuMVC Project



Happy Coding!

Saturday, May 29, 2010

Using Sql to generate C# properties

I am working on a project which entails myself and another developer Todd Wood to build our business objects with properties (a small piece of the project) matching the Oracle table column names.  Surely this is not hard to accomplish however, very tedious considering the table/column count.  My first thoughts were to use CodeRush to generate the properties faster than hand typing each of them.  However, Todd in all his brilliance decided to take another approach.  Instead he wrote a set of queries which will read the table's metadata and generate the properties for us.  Not only does it generate the properties, it takes nullable into consideration and generates nullable types as well.  Another item he took into account was we needed to read the data into the properties at some point, so naturally he wrote a script to generate the reader code for us as well.
As Genius Beer makers would say, Brilliant, just Brilliant!
So how did he do this? lets take a look at the Sql:


-- Data Reader populate

select replace(initcap(column_name), '_') || ' = ' || decode(data_type, 'NUMBER', 'Convert.ToInt32(reader["' || column_name || '"]),', 'DATE', '(!reader.IsDBNull(' || to_char(column_id - 1) || ')) ? Convert.ToDateTime(reader["' || column_name || '"]) : (DateTime?)null,', 'VARCHAR2', 'reader["' || column_name || '"] as String,', 'CHAR', 'Convert.ToChar(reader["' || column_name || '"]),' )
from user_tab_columns
where table_name = '{Your Table Name}'
order by column_id





-- Get / Set



select 'public ' || decode(data_type, 'NUMBER', 'int'|| decode(nullable, 'Y','?') , 'DATE', 'DateTime'|| decode(nullable, 'Y','?') , 'VARCHAR2', 'string', 'CHAR', 'char'|| decode(nullable, 'Y','?') ) || ' ' || replace(initcap(column_name), '_') || ' { get; set; }'
from user_tab_columns
where table_name = '{Your Table Name}'
order by column_id;



Now keep in mind this was designed to run against an Oracle database, however it can be converted to your DB of choice with some tweaks here and there (Don't quote me on this as I am no DBA by any means ;), but "It should probably work"). 
So what happens when this is run against the DB?


When you run the Reader script your output will look something like this when run against the USER_TAB_COLUMNS table in Oracle:



TableName = reader["TABLE_NAME"] as String,
ColumnName = reader["COLUMN_NAME"] as String,
DataType = reader["DATA_TYPE"] as String,
DataTypeMod = reader["DATA_TYPE_MOD"] as String,
DataTypeOwner = reader["DATA_TYPE_OWNER"] as String,
DataLength = Convert.ToInt32(reader["DATA_LENGTH"]),
DataPrecision = Convert.ToInt32(reader["DATA_PRECISION"]),
DataScale = Convert.ToInt32(reader["DATA_SCALE"]),
Nullable = reader["NULLABLE"] as String,
ColumnId = Convert.ToInt32(reader["COLUMN_ID"]),
DefaultLength = Convert.ToInt32(reader["DEFAULT_LENGTH"]),
NumDistinct = Convert.ToInt32(reader["NUM_DISTINCT"]),
Density = Convert.ToInt32(reader["DENSITY"]),
NumNulls = Convert.ToInt32(reader["NUM_NULLS"]),
NumBuckets = Convert.ToInt32(reader["NUM_BUCKETS"]),
LastAnalyzed = (!reader.IsDBNull(18)) ? Convert.ToDateTime(reader["LAST_ANALYZED"]) : (DateTime?)null,
SampleSize = Convert.ToInt32(reader["SAMPLE_SIZE"]),
CharacterSetName = reader["CHARACTER_SET_NAME"] as String,
CharColDeclLength = Convert.ToInt32(reader["CHAR_COL_DECL_LENGTH"]),
GlobalStats = reader["GLOBAL_STATS"] as String,
UserStats = reader["USER_STATS"] as String,
AvgColLen = Convert.ToInt32(reader["AVG_COL_LEN"]),
CharLength = Convert.ToInt32(reader["CHAR_LENGTH"]),
CharUsed = reader["CHAR_USED"] as String,
V80FmtImage = reader["V80_FMT_IMAGE"] as String,
DataUpgraded = reader["DATA_UPGRADED"] as String,
Histogram = reader["HISTOGRAM"] as String,





Notice how the script writes C# code for you ready to be put to work.  Take a look at LastAnalyzed, its smart enough to handle the tertiary code as well! Now let's see what the property script will output for the same table:



public string TableName { get; set; }
public string ColumnName { get; set; }
public string DataType { get; set; }
public string DataTypeMod { get; set; }
public string DataTypeOwner { get; set; }
public int DataLength { get; set; }
public int? DataPrecision { get; set; }
public int? DataScale { get; set; }
public string Nullable { get; set; }
public int? ColumnId { get; set; }
public int? DefaultLength { get; set; }
public DataDefault { get; set; }
public int? NumDistinct { get; set; }
public LowValue { get; set; }
public HighValue { get; set; }
public int? Density { get; set; }
public int? NumNulls { get; set; }
public int? NumBuckets { get; set; }
public DateTime? LastAnalyzed { get; set; }
public int? SampleSize { get; set; }
public string CharacterSetName { get; set; }
public int? CharColDeclLength { get; set; }
public string GlobalStats { get; set; }
public string UserStats { get; set; }
public int? AvgColLen { get; set; }
public int? CharLength { get; set; }
public string CharUsed { get; set; }
public string V80FmtImage { get; set; }
public string DataUpgraded { get; set; }
public string Histogram { get; set; }



And there you have it folks, a nicely generated set of properties and readers to populate the properties based on your tables columns/names.  Many thanks to Todd Wood for these great scripts.

Thursday, January 14, 2010

Set an ActiveX as Trusted and make calls to Javascript functions

There comes a time when you need to write an ActiveX for reasons that really don't matter in this post but you know those times.  I personally try to avoid them due to their "Windows Only Support" but in a recent project where we had to integrate a java web based application with an application I wrote in C# that was a Winforms application the need was eminent.  We needed a way to fire up the winforms application from the web, pass it some parameters, and when it closes notify the page as well as give the page some data the user entered.  Well getting a web page to open a windows application is pretty simple however we needed much more than just opening the applciation and forgetting about it.  A problem we were facing was how are we going to:

1. Notify the calling page when the form closes
2. Return user entered data back into the page

The client has a policy on their in-house applications that they only support IE.  So we knew from that we could build an ActiveX and not worry about other browsers.  I mean hey, IE works very well with ActiveX and FireFox not so much.  We needed the code to notify the page via javascript because a postback was not allowed for this application.  It appeared the java web app uses a redirect similar to the way Server.Transfer works in ASP.NET in which the Url stays on the base directory.  If a postback was fired then the user would be taken back to their dashboard and lose what they had entered.  So the idea to write an ActiveX was decided as the approach we would take.  We still needed to know if it was possible to make a call to a Javascript function from an ActiveX.  After much research I found a solution using the IOleClientSite Interface.  This interface allows you to get the container the ActiveX is hosted in.  Then using the IHTMLDocument2 interface we can gain access to the DOM.

Here is an example:

/// <summary>
/// Calls the JScript within the current DOM this activeX is placed in.
/// </summary>
/// <param name="key">The key.</param>
private void CallJScript(string key)
{
try
{
// Get a handle on the current Page
Type typeIOleObject = this.GetType().GetInterface("IOleObject", true);

// Get the ClientSite
object oleClientSite = typeIOleObject.InvokeMember("GetClientSite",
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
null, this, null);

// Obtain the container
IOleClientSite oleClientSite2 = oleClientSite as IOleClientSite;
IOleContainer pOleContainer;
oleClientSite2.GetContainer(out pOleContainer);

IHTMLDocument2 pDoc1 = (IHTMLDocument2)pOleContainer;

// Gain access to its DOM
object script = pDoc1.Script;

// Create the arguments that will be passed
// as parameters to the javascript function
object[] args = new object[1];
args[0] = key;

// Invoke the script
script.GetType().InvokeMember("YourJavaScriptFunction", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, script, args);
}
catch
{
// TODO: Log Message
}
}


This seemed simple enough until we put the ActiveX on the page and discovered it wasn't working.  I was so confused because from everything I had read this is how you do it.  After more research and debugging I discovered the ActiveX didn't have permission to access the DOM; it was being denied by IE.  So once again more research on how to get access to the ActiveX because setting the site as Trusted wasn't enough.  I came across another site (I wish I could find it again to display here) which led me in the right direction on how to get this working.  You have to create an interface named IObjectSafety which will let IE know the ActiveX is safe.  To make this work you create an enum that is Serializable and ComVisible like so:



[Serializable, ComVisible(true)]
public enum ObjectSafetyOptions
{
INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001,
INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002,
INTERFACE_USES_DISPEX = 0x00000004,
INTERFACE_USES_SECURITY_MANAGER = 0x00000008
};


Then you need to create an Interface called IObjectSafety like so:



/// <summary> 
/// IObjectSafety lets IE know this ActiveX is safe
/// </summary>
[ComImport(), Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IObjectSafety
{
[PreserveSig]
long GetInterfaceSafetyOptions(ref Guid iid, out int pdwSupportedOptions, out int pdwEnabledOptions);

[PreserveSig]
long SetInterfaceSafetyOptions(ref Guid iid, int dwOptionSetMask, int dwEnabledOptions);
};


 
And then you create your control (I used UserControl) which will be used to talk between the Page and the Windows Form. 



[ClassInterface(ClassInterfaceType.AutoDual),
ComSourceInterfaces(typeof(ControlEvents))]
[Guid("F7A01F7B-C6B8-4076-9313-A976EE45C472")]
[ComVisible(true)]
public partial class MyClass : UserControl, IObjectSafety
{
...
}


The IObjectSafety member was implemented as:



#region IObjectSafety Members
private ObjectSafetyOptions m_options =
ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER |
ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA;

/// <summary>
/// Gets the interface safety options.
/// </summary>
/// <param name="iid">The iid.</param>
/// <param name="pdwSupportedOptions">The PDW supported options.</param>
/// <param name="pdwEnabledOptions">The PDW enabled options.</param>
/// <returns></returns>
public long GetInterfaceSafetyOptions(ref Guid iid, out int pdwSupportedOptions, out int pdwEnabledOptions)
{
pdwSupportedOptions = (int)m_options;
pdwEnabledOptions = (int)m_options;
return 0;
}

/// <summary>
/// Sets the interface safety options.
/// </summary>
/// <param name="iid">The iid.</param>
/// <param name="dwOptionSetMask">The option set mask.</param>
/// <param name="dwEnabledOptions">The enabled options.</param>
/// <returns></returns>
public long SetInterfaceSafetyOptions(ref Guid iid, int dwOptionSetMask, int dwEnabledOptions)
{
return 0;
}

#endregion


 
This is all it took to make the ActiveX have the permission it needed to gain access to the DOM and make DOM calls.  The use of the IObjectSafety makes an ActiveX that was once "untrusted" become "trusted".  I hope this helps you out and saves you the time I spent trying to get this working on our project.  As always, Happy Coding.

Wednesday, January 13, 2010

My personal experience with Alienware PC Maker

    Well on March 26th 2009 I purchased a Laptop from Alienware which I was very excited about after reading about the high performance components they use in their laptops.  I got my Laptop and quickly opened it and was ready to conquer my development tasks… well probably not quite like that but you get the point.  All was going great, I was installing Visual Studio 2008 and got that done; then went on to install DevExpress but before I got a chance to install it the laptop froze up.  The screen stayed on the way I left it and the cursor would not move.  I immediately called Technical Support since these things shouldn’t be happening and I happened to have purchased the extended warranty.  Technical Support had me reboot, which consisted of holding the power button down for 3-5 seconds.  Then they asked me to download a third-party program (SpeedFan) so we could check if the PC was getting hot while a memory check was run using both chips installed.  Then we ran a Video Card test and monitored the PC heat.  All seemed to be doing well until we tested Memory using a single chip at a time and some hiccups happened.  First attempt froze the machine and subsequent attempts seemed to be fine.  We could not figure out why the PC was freezing.  So we gave up and went on thinking it must be drivers or something.  I updated the drivers to the latest versions and even flashed the bios with a new upgrade that was available.  The PC kept freezing about once a week, then once a day and I was getting flustered.  I called Support again and once again we ran a memory check (Extensive Check) on what I now have installed Windows 7.  No results found, the memory passed.  So then we ran a chkdisk with the options to repair bad clusters checked and of course no issues with the exception of 2 bad clusters which windows reports it fixed.  After hours with a Technician and no idea why this pc is freezing he puts me on hold and another guy gets on the line.  The new guy gets on just to tell me that because I upgraded to Windows 7 my warranty is no longer going to support the problem I am experiencing with my laptop and that if I want to upgrade my support a charge will be required.  I asked if I paid this upgrade fee could they guarantee I would get the laptop fixed since of course it has had this problem since day 1 and I could go about my business.  I was told that they could not guarantee it would be fixed but they would try.  So basically what it boils down to is the following:

1. Paid for extended support – Not any good to me now since I upgraded to Windows 7
2. They want to charge me more – Cannot guarantee it will be fixed
3. I’m stuck with a laptop that keeps freezing and has been literally the day I got it

I was furious, I asked the guy if they test their equipment before sending it to the customer, he exclaimed they only test that it installed the OS and not for any other issues (Hardware or Software).  All in all I have learned a valuable lesson, I for one will not purchase extended warranties again on PC’s and I am done with Alienware products.  Not to say your experience will not be an enjoyable one but for me it has been a nightmare.  If you too have had a bad experience with Alienware I would like to hear from you and your experience.

Wednesday, December 09, 2009

Leaping into BDD

As this title says Leaping into BDD I have plunged in to learn about and use BDD.  My experience with it is new and I don’t claim to know everything about BDD.  With this said if you have some more insight or explanations you want to indulge us with please don’t hesitate to broaden our knowledge by sharing yours. 

We have all heard of Test Driven Development (TDD) and many of us have used it.  I’m going to tell you about a newer type of development out that in my opinion produces a much easier flow.  The new development is called Behavior Driven Development or BDD.  BDD is exactly as it is named, it specifies your code from a behavioral approach.  By the time we start to code we know what we want the project to do because we have already thought this out by now.  So using BDD we can write specifics to guide our code.  As an example, lets say we are writing a notepad application.

Our specifics may look something like this:

Open Text File for Editing
    - File Open Dialog with Filters
    - Content of file is extracted and placed onto Rich Text Box
Save Changes
    - Collect text and save back to opened file
Close Notepad
    - Check for changes made
        - if changes prompt user
    - Cleanup code
    - Close application

These specifications are pretty straight forward; we are thinking like a human and how a human would use our application.  In these scenarios we would have the option to open a file; OK, after the file is opened what do we do? Well according to our specs we can save the file, and we can close the application.  During a close we are showing that our application should check for changes and prompt the user if any exist.  Handle our cleanup of code and resources, then close the application.  Pretty straight forward right?

To get started using BDD you must first get the following:

- MSpec (Machine.Specifications)
- TestDriven.Net Personal/Professional (Not Required but good for running your test)

 

Once you have downloaded MSpec and unzipped, you will have something like this:

MSpecDir

 

Double click on the build batch file to run the compiler against the code and output the assemblies we need.
Note: You may receive errors on Resharper if you don’t have that installed, don’t worry about those.  You may also have to open the solution in Source and manually compile.

Lets get started by opening Visual Studio, I’m going to create a class called BDD to hold our properties.  But first before I do that I need to know my specifications, lets do that:

BooleanProp is true
- DoubleProp must be greater than 0
- IntegerProp must be 0
BooleanProp is false
- DoubleProp must be 0
- IntegerProp must be greater than 0

So I know I will have 3 properties, BooleanProp, IntegerProp, and DoubleProp.  First context I am saying if the BooleanProp is set to true then DoubleProp must be greater than zero and IntegerProp must be zero.  With this said, lets create a class with these properties.

public class BDD
{
private int _IntegerProp;
public int IntegerProp
{
get { return _IntegerProp; }
set
{
_IntegerProp = value;
}
}

private double _DoubleProp;
public double DoubleProp
{
get { return _DoubleProp; }
set
{
_DoubleProp = value;
}
}

private bool _BooleanProp;
public bool BooleanProp
{
get { return _BooleanProp; }
set
{
_BooleanProp = value;
}
}
}


Now that I have my class I’m going to write out the specifications in code.  I start by created a class, ill call it BDDSpecifications.



using Machine.Specifications;

public class BDDSpecification
{
/*
* BooleanProp is true
* - DoubleProp must be greater than 0
* - IntegerProp must be 0
* BooleanProp is false
* - DoubleProp must be 0
* - IntegerProp must be greater than 0
*
*/

[Subject("BooleanProp is true")]
public class When_BooleanProp_is_true : BDDClass
{
Because of = () =>
{
testClass.BooleanProp = true;
};

It should_have_doubleProp_GreaterThanZero = () =>
{
testClass.DoubleProp.ShouldBeGreaterThan(0);
};

It should_have_integerProp_equal_zero = () =>
{
testClass.IntegerProp.ShouldEqual(0);
};
}

[Subject("BooleanProp is false")]
public class When_BooleanProp_is_false : BDDClass
{
Because of = () =>
{
testClass.BooleanProp = false;
};

It should_have_doubleProp_equal_zero = () =>
{
testClass.DoubleProp.ShouldEqual(0);
};

It should_have_integerProp_GreaterThanZero = () =>
{
testClass.IntegerProp.ShouldBeGreaterThan(0);
};
}

public abstract class BDDClass
{
protected static BDD testClass;
Establish context = () =>
{
testClass = new BDD();
};
}
}


Here you can see my specifications in code.  I have an abstract class, this is not required but prevents me from having to create the BDD class for each test.  Notice my classes inherit the BDDClass.  Looking at the code you might be a little nervous, don’t be.  The code is actually very simple,



Because of Something, It should have/do this, It should have/do that, etc, etc, etc.



 



If you did not install the TestDrive.Net, no problem.  When you compiled the source for MSpec an executable was generated called mspec in the build output.  Open your Tools->External Tools, click on Add.



Parameters:



Title: Add a title

Command: The path to the mspec.exe file


Arguments: $(TargetName)$(TargetExt) --html $(ProjectDir)Reports\report.html  
(Note: By adding the –-html “Report Path” an html file will be created for you with the results.  The html part is not required.)


Initial Directory: $(BinDir)



image



 



Now that you have your specifications all laid out, lets run this.  I'm going to run using the MSpec option.




My Results:


image



I have 2 that failed which I expected.  To make these pass I need to make some changes.



public class When_BooleanProp_is_true : BDDClass
{
Because of = () =>
{
testClass.BooleanProp = true;
testClass.IntegerProp = 0;
testClass.DoubleProp = 2;
};







I made a simple change to both classes and got the following results:





image



 



All specifications passed!! The report generated is a nice addition that can be printed and handed over to your PM.



 



Happy Coding…

 
Creative Commons License
Blogged Information and Code is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.