Wednesday, June 8, 2011

Running Machine.Specifications console runner in mixed mode

Our test project has just been upgraded to .NET 4.0. That caused some problems with the .NET 2.0 references, particularly SQLite. Here's the error you get right after a Nuget install:


NHibernate.HibernateException: Could not create the driver from NHibernate.Driver.SQLite20Driver, NHibernate, Version=3.1.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: Unable to find the requested .Net Framework Data Provider.  It may not be installed.

This is a well-known issue. Basically, SQLite is a .NET 2.0 targeted app. I am working in .NET 4.0. I followed Mohamed Meligy's instructions and added some edits to my test assembly's configuration file (app.config).


ReSharper and MSPEC ran my specs just fine. So, I then ran my MSBUILD project. I have a target that runs the mspec.exe console runner. I get the HibernateException again.


What gives?


Well, it turns out that the executables that you "nuget" from the package don't include configuration files. Sure, I had the edits for running mpsec from within Visual Studio's IDE using ReSharper's TestRunner. But mspec.exe is its own AppDomain -- you still need those configuration edits there.


To apply the configuration edits, you need a file. The nuget package didn't create them, so I did it manually.


In my packages/Machine.Specifications.0.4.12/tools folder, I created an mspec.exe.config file, and one for each of the other exe's. Inside, I placed the startup node with the legacy redirect. Additionally, I added the system.data node. Now, each mspec executable will leverage the mixed-mode framework setup to make SQLite happy.


Now, all tests pass just as they do in my test runner within my IDE.

Friday, February 5, 2010

Figuring out Rhino.Security and on-demand filtering

Ayende's Rhino.Security is an enterprise authorization framework. I recently added it to my Sharp Architecture project using Billy McCafferty's instructions and some help from Bart Reserhove's blog.

The next step is a spike to implement Rhino.Security authorization and then determining the best course of intercepting queries with permissions. Also, I understand that I can use the event subsystem in NHibernate, instead of an interceptor. I have to check both out.

Scrum: Now, bite sized!

Our small development team has been adopting Scrum using the Lightweight Scrum TFS template.

Adopting. I should say "attempting to adopt".

I have been researching the web for "freesources" on Scrum adoption, the lifecycle of a project, roles, user stories, implementation in a .NET shop, creating of executable specifications, etc.

Wow. Scrum is all over the place -- as in, widespread adoption and many opinions on proper implementation.

Our team is small -- two developers and a Scrum Master. Our initial sprint is for evaluation. We are tracking how to implement using a small bite-size project -- a simple display/edit screen. The user stories as of the moment don't even include authorization. We simply want to evaluate all of the scrum ceremonies and artifacts in action, in a short life-cycle.

What's more, we are also implementing our project using domain-driven design. If that seems like a recipe for failure, I disagree. The luxury we have is low visibility and a small enough team that we can communicate well.

Let's see how this goes.

Thursday, June 18, 2009

Mapping Method Properties with NHibernate, FNH

I have an experimental project that will likely evolve later with real specs and everything. With this greenfield of no intervention, I can spike away with NHibernate's hot-roddin' buddies: Fluent NHibernate and NHibernate.Linq.

Admittedly, I view NHibernate the way the monkey looked at the monolith in the movie 2001 : A Space Odyssey - a mixture of abject fear and wonderment. I have been flinging a lot of things at the "black-shiny" to no avail.

I want to implement the specifications pattern in Linq. The idea of having Linq specifications is very compelling. So off I toddled with my new bones in hand, ready to fling them with impunity at the "black-shiny".

I have an abstract User with value objects for a Person and Address. For this post, I will focus on the Person value object that contains name properties for first and last name. My end-users will want to be able to filter the User entity on those that contain a name part in the full name - a concatenation of first and last name.

Here's my code so far:

public class User : AbstractUser{

}
public abstract AbstractUser
{
public virtual Person Person {get; private set:}

}
public class Person{
public virtual string LastName {get; private set;}
public virtual string FirstName {get; private set;}

public Person (string firstName, string lastName){
FirstName = firstName;
LastName = lastName;
}

public string FullName{
get{
return string.Format("{0} {1}", FirstName, LastName);
}
}
}

OK, that's fine. Now, I need to map my User entity. Mapping is trivial using Standard Mapping in Fluent NHibernate. I will also include my Person value object as a convention, so I can re-use that again as needed.

public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.Id).GeneratedBy.Identity();
Component(x =>
x.Person, PersonConvention.MapPerson(""));
}
}
public class PersonConvention
{
public static Action<ComponentPart<Person>> MapPerson(string columnPrefix)
{
return p =>
{
p.Map(n => n.FirstName).WithLengthOf(50);
p.Map(n => n.LastName).WithLengthOf(50);
p.Map(n => n.MiddleInitial).WithLengthOf(1);
};
}
}

Looks good so far. Now, I am using NHibernate.Linq and Linq.Specifications. I might know a portion of Mr. Smith's name, but not how to spell it. I need to filter those Users by their full name with a Contains on the full name.

    public class UserNameSpecification : QuerySpecification<User>
{
private readonly string _name;

public UserNameSpecification(string namePart)
{
_name = namePart;
}

public override Expression<Func<User, bool>> MatchingCriteria
{
get {
return u => u.Person.FullName.Contains(_name);
}
}
}

Now, I should be able to query for FullName, right? I mean: it's a method result of two properties, not a value. At least, that's what I thought at first.


When Linq.NHibernate transmogrifies the C# into HQL, it has no idea how to translate FullName into its component FirstName, LastName.

Hmm, I must have missed a step somewhere. NHibernate.Linq has no idea about the contents of my MatchingCriteria() method. For all it knows, FullName is a string property.

Wait a second... My FullName() method might as well be a string property!

So if I map FullName() to Fluent NHibernate - Sure, it becomes a column. But, I can control the contents in my domain. I can now persist the method property to my persistence mechanism (DDD-speak for database, in this instance) and use it for querying later.

Here's the updated PersonConvention


public class PersonConvention
{
public static Action<ComponentPart<Person>> MapPerson(string columnPrefix)
{
return p =>
{
p.Map(n => n.FirstName).WithLengthOf(50);
p.Map(n => n.LastName).WithLengthOf(50);
p.Map(n => n.MiddleInitial).WithLengthOf(1);
p.Map(n => n.FullName).SetAttribute("access","readonly");
};
}
}

In my Setup method, I have inserted a "first user". I have FullName marked with the readonly attribute. Now, I can use the FindAll and pass in my specification.


[Test]
public void can_find_by_full_name()
{
IQueryable<User> byfullname = userRepository.FindAll(new UserNameSpecification("first user"));
Assert.AreEqual(1, byfullname.Count());
}

It passes. By the way, my repository's FindAll with the Linq.Specification implementation is as follows:



public IQueryable<TResult> FindAll<TResult>(ISpecification<User, TResult> specification)
{
return specification.SatisfyingElementsFrom(FindAll());
}

Keep in mind that this is not the end-game for NHibernate. AST to HQL parser projects appear to be in the works. Hopefully, we will be able to pass the contents of a method to NHibernate parse that to HQL for us. But until that is complete, we have the option of persisting method property results that NHibernate.Linq can parse.

Special thanks on the resolution of this issue goes to Hudson Akridge for pointing me in the right direction. Also, I would be remiss if I did not extend thanks to Steven Burman, the Mostly Clean Coder. Steven's posts on Linq.Specifications is an excellent resource for his project. He was also very kind to assist on a question I had. Thanks again, guys.