Wednesday, May 22, 2013

ASP.NET Web API: Model Validation

Validation Attributes

When it comes to validation I'm a big fan of using validation attributes from the System.ComponentModel.DataAnnotations namespace.  When building a RESTful web service with ASP.NET Web API, its a good idea to validate data models before updating (PUT) or creating (POST) resources.  Thankfully, these validation attributes work (almost) perfectly in ASP.NET Web API applications.

Take a look at the following model:
public class Product
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [StringLength(256)]
    public string Description { get; set; }
}
The Name property is required (cannot be null) and the Description property cannot be longer than 256 characters (never mind why the Name property does not have a size limit - the client has strange business rules ha ha).

So with my model all attributeified I can do something like this in my controller:
public class ProductsController : ApiController
{
    public HttpResponseMessage Post(Product product)
    {
        if (ModelState.IsValid)
        {
            //Controller logic here

            return new HttpResponseMessage(HttpStatusCode.OK);
        }
        else
        {
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }
    }
}
But Kerby, are you saying that I have to check if the ModelState is valid in all of my PUT/POST action methods?  That seems like a lot of redundant typing!  Quite right!  What drives good programming is the compulsive need to find more efficient ways to do things (laziness), and repetitively checking the ModelState validity is not efficient!  The way out of this quagmire will be in my next post about Action Filters.  So stay tuned.

Value Type Gotcha

When PUTting or POSTing data to a RESTful web service, that data is often represented as JSON or XML.  So it is important to understand that the validation attributes that belong to or inherit from System.ComponentModel.DataAnnotations only apply to the model object itself (post serialization) and NOT to the actual JSON/XML.

Using the example above, lets add a new property to our model:
public class Product
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [StringLength(256)]
    public string Description { get; set; }
    [Required]
    public int InventoryNumber { get; set; }
}
The InventoryNumber is an integer and is required (cannot be null).  Lets say the API receives a PUT request with the following JSON:

{"id":244, "name":"WidgetX", "description":"It's a secret"}

Notice anything missing?  Yup, InventoryNumber, which is required, so, obviously, this should fail validation.  So what will actually happen?  Well the JSON serialization class (Json.NET if you're awesome) will materialize a Product object with an InventoryNumber equal to 0 and the object will pass validation.  Wait... Pass?  That doesn't sound right!  Why?
  1. Because value types like integers cannot be null; therefore, in the absence of an InventoryNumber name/value pair in the JSON, the InventoryNumber property will be set to it's default value, and 0 is the default value of an integer.
  2. Because 0 is not null.  Remember that the [Required] attribute simply means that a value should not be null.
So how do we fix this?  We have a few options

Range Attribute (crap)


We could, instead of using a [Required] attribute, use a [Range(1,2147483647]] attribute.  Therefore when the JSON above deserializes with a 0 value for InventoryNumber validation will fail!  But what if 0 is a legitimate value?  Yeah, this isn't a good solution.

Make it Nullable (great - for value types)


We could keep the [Required] attribute and just make InventoryNumber a nullable int.  That way, the JSON above would deserialize InventoryNumber to null and validation will fail!

One more scenario to consider...


What if null is a legitimate & valid value?  Well then don't use the [Required] attribute, duh!!  Yes, of course.  But remember how System.ComponentModel.DataAnnotations only apply to objects and NOT to JSON/XML?  Lets say that the client sends the following PUT request:

{"id":244, "name":"WidgetX", "inventoryNumber":5}

This time, the client left off the Description name/value pair.  So, when deserialized, the Product object's Description property will be null, pass validation, and be persisted that way in the database.  But did the client mean for it to be null or was it just forgotten?  Well, it's our API and we can design it with whatever rules we want. There's nothing stopping us from assuming that missing means null.  So from the client's perspective it's "Oops, I forgot to include the description and now it's gone and I've forgotten what it was before! Guess I need to stop being stupid!"  Problem solved!

Or...

We could be a little more stupid tolerant and kindly let the client know that they forgot the description.  Also, its probably better that we don't make assumptions anyway.  Remember, null can be a valid value for the description, so DataAnnotations validation attributes aren't going to help much here.  If only there were some way we can validate the JSON itself, before it gets deserialized into an object.  If you are awesome and using Json.NET then you're in luck!  The Json.NET class library includes an attribute called JsonPropertyAttribute which, among other useful things, allows you to specified that a property must be included in the JSON, but it's value can be null.

[StringLength(256)]
[JsonProperty(Required = Required.AllowNull)]
public string Description { get; set; }

Just to be clear, JsonPropertyAttribute is a part of Json.NET.  At this time I don't know know how the same thing could be accomplished using other JSON or XML serializers.

Happy validating!

Monday, January 21, 2013

Setting up Castle Windsor for ASP.NET Web API

For the past few weeks, I've been working on creating a RESTful web service using the new ASP.NET Web API framework. One particular problem that arose for me was how to handle dependency injection for controllers. Basic constructor injection won't work out of the box because the framework automatically creates the controllers for you and doesn't know anything about their dependencies. On the ASP.NET website, there's a helpful post discussing the use of the Web API Dependency Resolver which provides an example of how to create "A Simple Dependency Resolver" that can create objects that the framework requires at run time, including controllers. The example works just fine, but if your API has more than a few controllers it can become very cumbersome to maintain. This is where IoC (Inversion of Control) containers can be very handy. The ASP.NET post goes on to provide an example of how to use the Unity IoC container which was developed by Microsoft. I, however, wanted to explore other options of IoC containers to use. After doing quite a bit of research, I finally settled on using Castle Windsor.
If you are unfamiliar with the IoC technique, I highly recommend reading this 4-part article by Simone Busoli which talks about the overall concept of IoC as well as providing some Castle Windsor specific implementation.
Unfortunately, the specifics on how to setup and use Castle Windsor in an ASP.NET Web API project are a bit difficult to find and, at the moment, are scattered all over the internet. So, this post is my attempt to put it all together in one concise place. I don't go into great detail about some of the Castle Windsor specifics in my examples, but I've and provided links that should help fill in the blanks.

IDependencyResolver

First things first.  The ASP.NET Web API framework allows you to configure a custom "Dependency Resolver" which handles the instantiation of objects (like controllers) and their dependencies behind the scenes.  What we're going to do is create a custom "WindsorDependencyResolver" which, as it's name implies, resolves dependencies using the Castle Windsor container.  Our WindsorDependencyResolver will need to implement System.Web.Http.Dependencies.IDependencyResolver (NOT System.Web.Mvc.IDependencyResolver).  Our class will initially look like this:
public class WindsorDependencyResolver : IDependencyResolver
{
 public IDependencyScope BeginScope()
 {
  throw new NotImplementedException();
 }

 public object GetService(Type serviceType)
 {
  throw new NotImplementedException();
 }

 public IEnumerable<object> GetServices(Type serviceType)
 {
  throw new NotImplementedException();
 }
 
 public void Dispose()
 {
  throw new NotImplementedException();
 }
}
The first thing our new class needs is an actual Windsor Container.  So lets add a private field and call it _container, as well as a constructor to instantiate it. While we're at it we can implement the GetService, GetServices and Dispose methods:
public class WindsorDependencyResolver : IDependencyResolver
{
 private readonly IWindsorContainer _container;

 public WindsorDependencyResolver(IWindsorContainer container)
 {
  _container = container;
 }
 public IDependencyScope BeginScope()
 {
  throw new NotImplementedException();
 }

 public object GetService(Type serviceType)
        {
         if(_container.Kernel.HasComponent(serviceType)
          return this._container.Resolve(serviceType);
         else
          return null;
        }

 public IEnumerable<object> GetServices(Type serviceType)
 {
  return _container.ResolveAll(serviceType).Cast<object>();
 }

 public void Dispose()
 {
  _container.Dispose();
 }
}
Notice that even in our dependency resolver class, we're still using a good dependency injection pattern. The IWindsorContainer interface will be implemented by a WindsorContainer object which we will discuss in detail later. The GetService, GetServices, and Dispose methods will be calling the Resolve, ResolveAll, and Dispose methods of the injected WindsorContainer object. It is important to note that the GetService method should return null if the component was not available, this will ensure that the framework default implementation will be used instead.

IDependencyScope (borrowing heavily from Can Gencer's post)

During the life-cycle of a request, a dependency scope (implemented by IDependencyScope) is created on the request using the BeginScope method on the IDependencyResolver. You guessed it, we need to create our own implementation of IDependencyScope. Since IDependencyResolver inherits from IDependencyScope, our "WindsorDependencyScope" implementation will look pretty similar to our "WindsorDependencyResolver" one:
public class WindsorDependencyScope : IDependencyScope
{
 private readonly IWindsorContainer _container;
 private readonly IDisposable _scope;

 public WindsorDependencyScope(IWindsorContainer container)
 {
  this._container = container;
  this._scope = container.BeginScope();
 }

 public object GetService(Type serviceType)
 {
  if (_container.Kernel.HasComponent(serviceType))
   return _container.Resolve(serviceType);
  else
   return null;
 }

 public IEnumerable<object> GetServices(Type serviceType)
 {
  return this._container.ResolveAll(serviceType).Cast<object>();
 }

 public void Dispose()
 {
  this._scope.Dispose();
 }
}
The Scoped Lifestyle is a new lifestyle in Castle Windsor 3 that makes it possible to create an arbitrary scope bounded by the object returned from the Container.BeginScope call. When this object is disposed, the scope is ended and Castle will then release all the objects with Scoped lifestyle that have been resolved in the same call stack after the scope is generated. Our WindsorDependencyResolver's BeginScope method can now be updated:
public IDependencyScope BeginScope()
{
   return new WindsorDependencyScope(_container);
}
With our WindsorDependencyResolver and WindsorDependencyScope implementations, we're ready to register our components (using installers) and then replace the default dependency install with our Windsorified one.

Windsor Installers

I don't want to spend too much time on this, but in order for the Windsor IoC container to work, your application's services (interfaces) and components (concrete implementations) must be registered. Windsor uses Installers to encapsulate and partition the registration logic. You can read all about Installers and how to use them on Windsor's website. Windsor strongly recommends that a "single installer installs some coherent closed set of related services (like repositories, controllers, etc), and you have separate installer for each of these sets." So, this means that we should write one installer that is dedicated to our controllers, and another installer for the stuff (repositories for example) that our controllers depend on, and so forth. Assuming all of our controllers inherit from ApiController abstract class, our controller installer could look like this:
public class ApiControllersInstaller : IWindsorInstaller
{
 public void Install(Castle.Windsor.IWindsorContainer container, Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore store)
 {
  container.Register(Classes.FromThisAssembly()
   .BasedOn<ApiController>()
   .LifestylePerWebRequest());
 }
}
Generally speaking, the lifestyle of a controller (and it's dependencies) should be "per web request." Remember, you'll need a separate installer for each separate set of related services. So if you have a typical MVC/Web API architecture with Controllers that depend on Business Services, which depend on Data Repositories then you'll need at least three separate installers (one for each layer).

Putting it All Together

Now we're ready to put everything together. Somewhere inside the Application_Start method of Global.asax add the following lines of code:
IWindsorContainer container = new WindsorContainer();
container.Install(FromAssembly.This());
config.DependencyResolver = new WindsorDependencyResolver(container);
First we instantiate a new WindsorContainer. Then we install our installers into the container, utilizing the FromAssembly helper method. Finally we replace the default dependency resolver with our custom WindsorDependencyResolver.
Happy injecting!

Friday, January 18, 2013

Entity Framework and the Data Access Layer: Generic Repository

Yet another installment of my posts about Entity Framework and the Data Access Layer.  In my previous posts I suggested creating CRUD methods for each entity type in your data model.  The downside to that approach is that if you have a lot of entity types in your model, you'd have do do a lot of typing.  Instead, we can use generics to build a single repository that can be used with any entity (POCO) type. In my examples below I'm using the DbContext class as the underlying context along with POCO entities.

Repository Interface

public interface IDbContextRepository : IDisposable
{
 void AttachAsModified<TEntity>(TEntity entity, params string[] propertyNames) where TEntity : class;

 void AttachAsModified<TEntity>(TEntity entity) where TEntity : class;

 void Delete<TEntity>(TEntity entity) where TEntity : class;

 IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;

 IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> predicate, params string[] includes) where TEntity : class;

 IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class;

 void Insert<TEntity>(TEntity entity) where TEntity : class;

 IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class;

 IQueryable<TEntity> GetQuery<TEntity>(params string[] includes) where TEntity : class;

 int SaveChanges();
}

This interface defines basic CRUD-like methods with a couple of overloads here and there (more about these later) along with a SaveChanges method. Notice that this interface inherits from IDisposable. Also notice how some methods return IEnumerable while others return IQueryable. This is deliberate. Returning IQueryable allows consumers to continue to build their own custom queries independent of what the data layer provides out of the box.

Base Repository Class

public abstract class DbContextRepository<TContext> : IDbContextRepository where TContext : DbContext
{
 private TContext _context;
 
 protected TContext Context
 {
  get { return _context; }
  set { _context = value; }
 }
 
 protected DbContextRepository(TContext dbContext)
 {
  _context = dbContext;
 }
 
 public void AttachAsModified<TEntity>(TEntity entity, params string[] propertyNames) where TEntity : class
 {
  if (_context.Entry(entity).State == EntityState.Detached) //entity is detached
  {
   //Attach
   _context.Set<TEntity>().Attach(entity);
  }

  //Specifiy which specific properties are modified
  foreach (string propertyName in propertyNames)
  {
   _context.Entry(entity).Property(propertyName).IsModified = true;
  }
 }

 public void AttachAsModified<TEntity>(TEntity entity) where TEntity : class
 {
  if (_context.Entry(entity).State == EntityState.Detached) //entity is detached
  {
   //Attach
   _context.Set<TEntity>().Attach(entity);
  }

  //Set the entity's state as Modified
  _context.Entry(entity).State = EntityState.Modified;
 }

 public void Delete<TEntity>(TEntity entity) where TEntity : class
 {
  DbSet<TEntity> dbSet = _context.Set<TEntity>();
  if (_context.Entry(entity).State == EntityState.Detached) //entity is detached
  {
   //Attach
   dbSet.Attach(entity);
  }

  //Remove
  dbSet.Remove(entity);
 }

 public IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
 {
  return _context.Set<TEntity>().Where(predicate).AsEnumerable<TEntity>();
 }

 public IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> predicate, params string[] includes) where TEntity : class
 {
  var query = _context.Set<TEntity>().Where(predicate);
  foreach (string include in includes)
  {
   query.Include(include);
  }
  return query.AsEnumerable<TEntity>();
 }

 public IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class
 {
  return _context.Set<TEntity>().AsEnumerable<TEntity>();
 }

 public void Insert<TEntity>(TEntity entity) where TEntity : class
 {
  if (_context.Entry(entity).State == EntityState.Detached) //Entity is detached
  {
   _context.Set<TEntity>().Add(entity);
  }
  else //Entity is attached
  {
   _context.Entry(entity).State = EntityState.Added;
  }
 }

 public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
 {
  return _context.Set<TEntity>();
 }

 public IQueryable<TEntity> GetQuery<TEntity>(params string[] includes) where TEntity : class
 {
  var query = _context.Set<TEntity>();
  foreach (string include in includes)
  {
   query.Include(include);
  }
  return query;
 }

 public int SaveChanges()
 {
  return _context.SaveChanges();
 }

 public void Dispose()
 {
  _context.Dispose();
 }
}

There are several things to talk about here so I'll break it out in to sections.


AttachAsModified

As their name implies, these methods attach an entity to the context and sets it's state to Modified so that when SaveChanges is invoked, the entity is updated in the database. The difference between the overloads is that one will mark the entity as Modified along will All of it's properties. Therefore when saved, every property/field is updated in the database. The other overload allows the consumer to specify a list of properties so that when saved ONLY the specified properties/fields are updated.

Delete and Insert

These two methods are pretty strait forward.  The important thing to note about them is that before adding or removing the entity, they first ensure that the entity is attached to the context.  This ensures that the context is tracking the entity when it is subsequently added or removed.

Find vs GetQuery

These two method sets are similar in that they can be used to query entities from a database, but they are different in execution and what they return. The find methods accept a LINQ expression as a parameter named predicate.  You could think of this as a WHERE clause in a SQL statement.  You are trying to "find" a set of entities that is filtered by the predicate.  For example, if I wanted to "find" red cars:

List<Car> redCars = MyDataLayer.Find(car => car.Color == "Red").ToList();

The GetQuery method can also be used to "find" or query entities from a database, but instead of returning a collection of filtered entities, it simply returns a queryable object that can be used by the consumer to leverage LINQ's query building capability. For example:

bool doFilter = true;

var carQuery = MyDataLayer.GetQuery<Car>();
if (doFilter)
{
   carQuery = carQuery.Where(car => car.Color == "Red");
}

List<Car> cars = carQuery.ToList();

One other thing to mention about Find and GetQuery is the overloaded versions with the "includes" parameter. This allows the consumer to force Entity Framework to eagerly load related entities. The parameter is simply a string array who's items must match one of the navigation properties of the entity. For example if we have an entity of type Parent which has a navigation property named "Children" (which could be of type ICollection) then to eagerly load a parent with all of it's children:

var parentWithChildern = MyDataLayer.GetQuery<Parent>("Children").FirstOrDefault();

GetAll

Not much to explain here. This will simply return a collection of all entities from a table. Needless to say, use this with caution.

Finally, SaveChanges and Dispose are both pretty strait forward so I'm not going to take the time to explain them. Happy Coding!


Friday, May 11, 2012

Entity Framework and the Data Access Layer: POCO Entities

In an earlier post I discussed Entity Framework's role in the traditional data access layer.  I provided an example of a data access layer comprised of an interface and a concrete implementation class that provide basic CRUD methods for each entity in the data model.

Beginning in EF 4.0, the ADO.NET team introduced support for POCOs!!  Because POCOs have no persistence awareness, the method implementations in my previous post must be re-written.  Below are my new and improved method implementation (I've tried to make the comments self-explanatory).

public IQueryable Parents
{
    get { return context.Parents; }
}

/// 
/// Adds the specified Parent to the underlying context sets it in the Added state
/// such that it will be inserted into the database when SaveChanges is called.
/// 
/// The Parent
public void InsertParent(Parent parent)
{
    ObjectStateEntry entry = null;
    if (context.ObjectStateManager.TryGetObjectStateEntry(parent, out entry))
    {
        if (entry.State == EntityState.Detached) //Entity is Detached
        {
            //Add to object set
            context.Parents.AddObject(parent);
        }
        else //Entity is already Attached
        {
            //Change to Added
            context.ObjectStateManager.ChangeObjectState(parent, EntityState.Added);
        }
    }
    else //Assume parent is Detached
    {
        //Add to object set
        context.Parents.AddObject(parent);
    }
}

/// 
/// Attaches the specified Parent to the underlying context as modified
/// such that it will be updated in the database when SaveChanges is called.
/// 
/// The Parent
public void UpdateParent(Parent parent)
{
    ObjectStateEntry entry = null;
    if (context.ObjectStateManager.TryGetObjectStateEntry(parent, out entry))
    {
        if (entry.State == EntityState.Detached) // Entity is not attached
        {
            //Attach
            context.Parents.Attach(parent);
        }
    }
    else //Assume parent is not attached
    {
        //Attach
        context.Parents.Attach(parent);
    }

    //Set as Modified
    context.ObjectStateManager.ChangeObjectState(parent, EntityState.Modified);
}

/// 
/// Attaches the specified Parent to the underlying context as modified,
/// and sets each specified property as modified such that only the specified
/// properties will be updated in the database when SaveChanges is called.
/// 
/// The Parent
/// The property names
public void UpdateParent(Parent parent, IEnumerable propertyNames)
{
    ObjectStateEntry entry = null;
    if (context.ObjectStateManager.TryGetObjectStateEntry(parent, out entry))
    {
        if (entry.State == EntityState.Detached) //Entity is not attached
        {
            //Attach
            context.Parents.Attach(parent);
        }
    }
    else //Assume parent is not attached
    {
        //Attach and get the ObjectStateEntry
        context.Parents.Attach(parent);
        entry = context.ObjectStateManager.GetObjectStateEntry(parent);
    }

    //Set the parent's state as Modified
    entry.SetModified();

    //Specifiy which specific properties are modified
    foreach (string propertyName in propertyNames)
    {
        entry.SetModifiedProperty(propertyName);
    }
}

/// 
///  Marks the specified Parent as Deleted such that it will be deleted from the database
///  when SaveChanges is called.
/// 
/// The Parent
public void DeleteParent(Parent parent)
{
    ObjectStateEntry entry = null;
    if (context.ObjectStateManager.TryGetObjectStateEntry(parent, out entry))
    {
        if (entry.State == EntityState.Detached) //Entity is Detached
        {
            //Attach & set to Deleted
            context.Parents.Attach(parent);
            context.Parents.DeleteObject(parent);

        }
        else //Entity is already Attached
        {
            //Set to Deleted
            context.ObjectStateManager.ChangeObjectState(parent, EntityState.Deleted);
        }
    }
    else //Assume parent is Detached
    {
        //Attach & set to Deleted
        context.Parents.Attach(parent);
        context.Parents.DeleteObject(parent);
    }
}

As in my previous post, these methods must be safe to use in a stateless application (such as a WCF web service) that may be required to insert, update, or delete detached entities.  POCO entities do not have an EntityState property so we must use the context's ObjectStateManager in order to determine the entity's state.

I've also added an overload to the update method. In addition to the entity (parent) parameter, it also accepts an enumeration of strings that represent property names. Be default, entity framework will update all properties/fields of the specified entity in the datastore. This method is useful when you only want to update specific properties/fields.

Cheers!

Thursday, April 19, 2012

Entity Framework and the Data Access Layer

I've been developing using Entity Framework for some time now and I've spent a lot of time trying to determine where it best "fits" into an application. More particularly, how best to utilize Entity Framework and a data access layer in an n-tiered application architecture.

One of the advantages of a tiered application architecture is that it achieves a separation of concerns.  In the ideal application, each layer is loosely coupled and can be easily isolated for UNIT testing.  So, where does Entity Framework fit in?  The simplest approach would be to instantiate and use an EF object context directly in the business logic layer.  However, that approach makes isolating the business logic layer rather difficult because it has a concrete dependency (tightly coupled) on the object context.  After much debate within my own brain, I've finally settled an approach that plays to the strengths of Entity Framework (and LINQ for that matter) while maintaining the traditional separation of concerns, loose coupling, hi cohesion, and a bunch of other buzz words ;-)

First, create the entity model.  I won't bother going into the details of how this is done, but this is a good place to see how it can be done.  For this example I have created a very basic entity model with a Parent and a Child entity.

Next, to facilitate loose coupling, I create an interface which exposes CRUD-type methods and properties for working with the entities.

public interface IMyData
{
    public IQueryable Parents { get; }

    public void InsertParent(Parent parent);

    public void UpdateParent(Parent parent);

    public void DeleteParent(Parent parent);

    public IQueryable Children { get; }

    public void InsertChild(Child child);

    public void UpdateChild(Child child);

    public void DeleteChild(Child child);
}

Notice for each entity I've created an IQueryable, read-only property along with insert, update, and delete methods.

Okay, now it's time to build a concrete implementation of the interface.  I like to add a private reference to my entity model and initialize it in the constuctor like so:
private DataModelContainer _context;

public MyData()
{
    _context = new DataModelContainer();
}
Lets start with the IQueryable properties.  The data model container exposes an ObjectSet for each entity type so all we need to do is return that Object set in the getter:
public IQueryable Parents
{
    get { return _context.Parents; }
}
The insert, update, and delete methods are also fairly strait-forward.
public void InsertParent(Parent parent)
{
    if (parent.EntityState != EntityState.Detached)
        _context.ObjectStateManager.ChangeObjectState(parent, EntityState.Added);
    else
        _context.Parents.AddObject(parent);
}

public void UpdateParent(Parent parent)
{
    if (parent.EntityState == EntityState.Detached)
    {
        _context.AttachTo("Parents", parent);
        ObjectStateEntry parentEntry = _context.ObjectStateManager.GetObjectStateEntry(parent);
        parentEntry.SetModified();
        //Optional... Specifiy which properties can be modified...
        parentEntry.SetModifiedProperty("Name");
        parentEntry.SetModifiedProperty("Age");
    }
}

public void DeleteParent(Parent parent)
{
    if (parent.EntityState == EntityState.Detached)
        _context.Parents.Attach(parent);
    else
        _context.Parents.DeleteObject(parent);
}
Notice each of these methods contains logic to check for the entity state. This logic is useful when the DAL is being used in an application where the entities may be detached from the object context, like in a WCF application, for example. The update methods are really only necessary in these types of applications.
So what does this look like in a business logic layer?
public class MyBusinessLayer
{
    private IMyData _dal;

    public MyBusinessLayer() : this(new MyData()) { }

    public MyBusinessLayer(IMyData dal)
    {
        _dal = dal;
    }

    //Business Logic Implementation...
}
We have a loosely coupled data layer which is instantiated as the concrete MyData type in the default constructor, or which can be injected via the second constructor.

There you have it!!! This approach plays to all of the benefits of Entity Framework plus it achieves loose coupling and a nice separation of concerns.

Monday, January 9, 2012

Auto-generated DataGrid column headers.

The Silverlight DataGrid's column auto-generation feature is nice to use when conditions allow for it.  However, the column names might not always come out in a user friendly way.  For example, if you are binding to a collection of "Product" objects:
public class Product
{
     public string ProductName{ get; set; }
     public decimal Price{ get; set; }
}

The GridView column header for the ProductName property will be auto-generated to "ProductName", but what I really want in the column header is "Product Name". To do this, we need to use the DisplayAttribute of the System.ComponentModel.DataAnnotations namespace. The class definition would now look like this:
public class Product
{
     [Display(ShortName="Product Name")]
     public string ProductName{ get; set; }
     public decimal Price{ get; set; }
}

Problem Solved! The gridview column header now says "Product Name".

Saturday, December 17, 2011

I've Been Setup!

I spent the better part of yesterday trying to figure out an easy way to install a windows service application.  After a few hours of trial and error, I finally nailed the process down.  Assuming that we've already got a windows service solution ready in visual studio, do the following:

Create Service Installers
  1. In the windows service project, in the solution explorer, right-click on the service class (by default it's called Service1.cs) and click on View Designer.
  2. Click in the designer background to bring it into focus.
  3. IMPORTANT:  In the service's properties window, take note of the ServiceName property.  Change it if you want.
  4. Right click -> Add Installer.  This creates a ProjectInstaller class (ProjectInstaller.cs).  For more info about installers click here.
  5. In the ProjectInstaller designer click on serviceInstaller1.
  6. In the properties window of the serviceInstaller1, set the ServiceName property equal to the ServiceName property from step 3.
  7. Set the StartType to Automatic
  8. Back in the ProjectInstaller.cs designer, click serviceProcessInstaller1.
  9. Set the Account property to LocalSystem.
  10. Build the service project.
Right!  Now our service project is built, and it has installers that are required for it to run as a windows service.  So, now we need an easy way to get the service installed on a machine.

Setup Wizard to the Rescue!
In the following steps, we will be creating a setup project and adding custom actions to that project that will install the service.
  1. In the solution explorer, right-click the solution node -> Add -> New Project
  2. Under Installed Templates, expand Other Project Types and then expand Setup and Deployment.
  3. Select Visual Studio Installer.
  4. In the Templates pane, select Setup Wizard.
  5. On Page 1, click Next.
  6. On Page 2, select "Create a setup for a Windows application" and click Next.
  7. On Page 3, select the "Primary output from [your windows service project]" and click Next
  8. On Page 4, click Finish.
  9. In the solution explorer, right-click on the new setup project -> View -> Custom Actions.
  10. Right-click on the Install Node -> Add Custom Action.
  11. In the "Select Item in Project" dialog box, make sure "Application Folder" is selected.
  12. Repeat steps 10 & 11 for the Uninstall Node (this will ensure that the service is un-registered when it is uninstalled).
  13. Click OK.
  14. Click on OK again to select "Primary output from [your windows service project]".
  15. Rebuild the service project and the new setup project.
That's it!!!  Building the setup project will create a setup.exe and a [setup project name].msi in the target configuration (Debug, Release, etc) folder inside the setup project's root folder.  You can then run the .msi on the machine you wish to deploy the windows service to.

Extras
You can change the default folder in which your application's files will be installed on the target machine.
  1. In the solution explorer, Double-click the "Primary output from [your windows service project]" action.
  2. Click on "Application Folder" in the File System on Target Machine tree.
  3. In the properties window set DefaultLocation to the desired path.
To uninstall the windows service do the following:
NOTE:  Step 13 in the Setup Wizard to the Rescue section will alleviate the need to do this!
  1. In Add or Remove programs, uninstall the service application.
  2. Open an elevated command prompt and type
    sc delete [your service's name]