blog.cleverswine.net Kevin Noone

26Sep/111

WCF Client and the “using” Statement

As I was researching patterns and practices for a WCF client implementation, I came across a bug in the .Net implementation of ClientBase<T> (whether it's actually a bug is arguable). It's well documented on the web, but it could cause major headaches if you happened to miss it.

The core of the issue is that ClientBase<T> implements IDisposable. With this knowledge, just about any programmer would naturally wrap its usage in a using{} block. Digging deeper, you'll find that the ClientBase<T> Dispose() method simply calls Close() on the underlying connection. This is problematic because in certain connection states (such as "Faulted"), the Close() will fail. As I said, this is well documented elsewhere, for example: on MSDN, Stack Overflow, and here.

There are a few different solutions to this issue. I went with a simple Disposable wrapper...

// Get a disposable MyClientWrapper object
using(var clientWrapper = ClientFactory.GetMyClientWrapper())
{
    clientWrapper.Client.DoSomething();
}
 
public class MyClientWrapper : IDisposable
{
    private readonly MyClient _client;
 
    public MyClientWrapper(Binding binding, Uri endpoint)
    {
        // creates an instance of MyClient, which is derived from ClientBase<T>
        _client = new MyClient(binding, new EndpointAddress(endpoint.ToString()));
    }
 
    public MyClient Client
    {
        get { return _client; }
    }
 
    public void Dispose()
    {
        // safe dispose with extension method (below)
        _client.CloseProxy();
    }
}
 
// extension method for safe Close() on ClientBase<T>
public static void CloseProxy(this ClientBase<T> proxy) where T : class
{
    try
    {
        if (proxy.State != CommunicationState.Closed 
                && proxy.State != CommunicationState.Faulted)
        {
            proxy.Close(); // may throw exception while closing
        }
        else
        {
            proxy.Abort();
        }
    }
    catch (CommunicationException)
    {
        proxy.Abort();
        throw;
    }
}
Tagged as: 1 Comment
9Sep/110

Find/Kill a Linux Process by Name

I was doing some research to figure out how to easily kill a Linux process given part of it's name. It's fairly simple to do it manually, but if you didn't already know, programmers are lazy.

The first thing I was doing...
> ps aux | grep Foo
find the process ID (PID) with my eyes, and then kill it...
> kill -9 123456

Next, I started finding complex piped commands to find and extract the PID. For instance...
> pid=`ps -eo pid,args | grep Foo | grep -v grep | cut -c1-6`

and slightly simpler...
> ps aux | grep Foo | grep -v grep | awk '{print $2}'

Finally, I discovered pgrep and pkill. There are quite a few options for each command, but simply put:

To get the PID for a process with a name containing 'Foo'...
> pgrep Foo

To get the PID for a process with a command line containing 'Bar' (as in > Foo -n Bar)...
> pgrep -f Bar

31Aug/110

Canning Fever



Pasta Sauce and Blueberry Jam

Originally uploaded by cleverswine


Bren has canning fever. It all started with a canning book that she received as a Christmas present. Now, she has canned (or jarred as I like to call it) Salsa, Pasta Sauce, Blueberry Jam, and Sweet Pickles. The nice thing is that we'll be well stocked with food that we know is locally grown and chemical free.

Tagged as: , No Comments
18Jul/110

Slow Gardening



Bellpepper

Originally uploaded by cleverswine


This summer is getting off to a slow start, as are our vegetables. We planted tomatoes, cucumbers, zucchini, various peppers, and carrots. So far we haven't picked a thing. We've barely reached the 80s in temperature, and we've had more rain than usual. However, despite the lack of veggies, I'm personally enjoying the cool summer.

20Apr/110

Simple Moq

I recently worked on a project in which 90% of its tests were integration tests because the core purpose of the project was to interact with external entities. In an effort create more unit tests, I employed Moq (and lots of refactoring).  This is an example of basic Moq usage.

Let's say we have a repository that gets documents from a database.  The assumption is that a repository interface, IDocumentRepository, is being implemented.

In my case, I found it easier to deserialize results from file, rather than building the results by hand for each mocked response.  I used System.Xml.Serialization to serialize real responses to file.

Let's Moq it...

var mockRepository = new Mock<IDocumentRepository>();
 
// if the query is for text/plain documents only, mock a response for that
mockRepository.Setup(p => p.FindDocuments(
	It.Is<DocumentQueryParams>(q => q.MimeType == "text/plain")))
	.Returns(DeSerializeResults<List<Document>>("TextDocuments.xml"));
 
// use It.IsAny to return the same result regardless of the parameters
mockRepository.Setup(p => p.FindDocuments(
	It.IsAny<DocumentQueryParams>()))
	.Returns(DeSerializeResults<List<Document>>("AllDocuments.xml"));
Tagged as: No Comments
19Apr/110

My Favorite Albums (Right Now)

This is what I'm listening to...

The Record by FEAR

This is old school punk from the early 80s, when punk rock was a means of expression and rebellion.  This particular album is humorous and offensive, as punk should be.

Gothic Kabbalah by Therion

This isn't my favorite Therion album, but I've been listening to it a lot lately because of some catchy songs.  I find it good to write code to because it takes you to another world.

Soviet Kitsch by Regina Spektor

This is something that's generally outside of my musical tastes, but I like her quirky voice and odd lyrics.  She reminds me of a disturbed version of Tori Amos.

The Other Side of Time by Mary Fahl

I once claimed that Tarja has the greatest female voice, but I actually meant Mary Fahl.  This album is completely not my style of music (folk/new age/soft rock), but her voice is irresistible and addictive.

Mary Fahl

Tagged as: No Comments
17Mar/110

Complex XSDs as Embedded Resources

I was recently tasked with validating XML files against a very complex set of XSD schema files.  This is easily accomplished if your XSD files live on the filesystem, because the .Net xml resolver can find referenced schemas via a relative or absolute Uri.  In my case, the schema files were compiled as embedded resources in my project.  As expected, the XML schema loader didn't know how to find referenced schemas - it was likely searching for them  in the path of the running application.  To solve this, I had to help out the schema loader by implementing a custom resolver that knew how to pull schema from the embedded resources.  The code...

Implement a custom XmlUrlResolver to find schema references as embedded resources.

public class ManifestResourceResolver : XmlUrlResolver
{
    private readonly Assembly _resourceAssembly;
    private readonly string _baseNamespaceForReferences;
 
    public ManifestResourceResolver(Assembly resourceAssembly, string baseNamespaceForReferences)
    {
        _resourceAssembly = resourceAssembly;
        _baseNamespaceForReferences = baseNamespaceForReferences.EndsWith(".") ? baseNamespaceForReferences : baseNamespaceForReferences + ".";
    }
 
    override public object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
    {
        if (absoluteUri.IsFile)
        {
            var file = Path.GetFileName(absoluteUri.AbsolutePath);
            var stream = _resourceAssembly.GetManifestResourceStream(_baseNamespaceForReferences + file);
            return stream;
        }
        return null;
    }
}

Create a XmlSchemaSet, and set the XmlResolver property to the custom resolver implemented above. Then, load up the main XSD schema.

var xmlSchemaSet = new XmlSchemaSet();
xmlSchemaSet.XmlResolver = new ManifestResourceResolver(Assembly.GetExecutingAssembly(), "MyApp.Schemas");
using (var stream = Assembly.GetCallingAssembly().GetManifestResourceStream("MyApp.Schemas.MainSchema.xsd"))
{
    var xmlSchema = XmlSchema.Read(stream, null);
    xmlSchemaSet.Add(xmlSchema);
}

Create a XmlReaderSettings object and set the Schemas property to the schema set loaded above. Lastly, load up an XML file with an XmlReader and read it.

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas = xmlSchemaSet;
settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
 
XmlReader reader = XmlReader.Create("SomeXml.xml", settings);
while (reader.Read());

The validation callback function will be invoked on each validation error while reading the file with the XmlReader.

private static void ValidationCallBack(object sender, ValidationEventArgs e)
{
    Console.WriteLine("Validation Error: {0}", e.Message);
}

References:

Tagged as: No Comments
13Mar/110

Local Groceries

We did this week's grocery shopping at Food Front in the Hillsdale neighborhood.  They carry many local and organic food products.  And, it may be my imagination, but local eggs fresh from the chicken taste so much better than the mass produced commercial eggs.

Tagged as: , No Comments
8Mar/112

MVC3 + MongoDB + Autofac

I recently posted a brief summary of creating a recipe database.  I decided to expand on that and go into the implementation details of using ASP.NET MVC3 with MongoDB and Autofac.  This code depends on the NoRM driver for MongoDB, Autofac, and MVC3 (and it's dependencies). This is by no means the only (or best) way to do things, but this is how I chose to do it.  I've simplified the repository to one method for brevity, but you'd obviously want to add all of the required CRUD operations.

First, we'll want to create an interface for our database session.  The implementation of this interface can be swapped out depending on the backing store.

1
2
3
4
public interface ISession : IDisposable
{
    System.Linq.IQueryable<T> All<T>() where T : class, new();
}

Add a MongoDB implementation of ISession.  This implementation will eventually be used in our repository.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MongoSession : ISession
{
    private readonly IMongo _provider;
 
    public MongoSession()
    {
        //this looks for a connection string in your Web.config
        //<connectionStrings>
        //  <add name="db" connectionString="mongodb://localhost/testdb?strict=true"/>
        //</connectionStrings>
        _provider = Mongo.Create("db");
    }
 
    public IQueryable<T> All<T>() where T : class, new()
    {
        return _provider.GetCollection<T>().AsQueryable();
    }
 
    public void Dispose()
    {
        _provider.Dispose();
    }
}

Create an interface for the repository.  This is what the controller will expect to be injected via it's constructor.

1
2
3
4
public interface IRecipeRepository
{
    IEnumerable<RecipeCard> GetAll(int page = 1, int pageSize = 10);
}

Add the IRecipeRepository implementation, which is created with a new()-able type of ISession.  Why didn't I just inject an ISession into the repository?  It's because Mongo sessions are expected to be disposed of after use, as connections are pooled and reused.  Therefore we have to create and dispose of our sessions when using them.  This might require some workarounds if you really did switch repositories (do nothing on Dispose(), etc).

1
2
3
4
5
6
7
8
9
10
public class RecipeRepository<SessionT> : IRecipeRepository where SessionT : ISession, new()
{
    public IEnumerable<RecipeCard> GetAll(int page = 1, int pageSize = 10)
    {
        using (var session = new SessionT())
        {
            return session.All<RecipeCard>().OrderByDescending(r => r.UpdatedDate).Skip(pageSize * (page - 1)).Take(pageSize).ToList();
        }
    }
}

Now it's time set up our IoC container.  We'll do this in the Global.asax.cs.  Here we are registering a recipe repository of type MongoSession such that any controller that expects an IRecipeRepository in the constructor will get this.  We're letting Autofac handle controller creation and dependency injection.  See the Autofac MVC3 integration page for more details.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected void Application_Start()
{
    var builder = new ContainerBuilder();
    builder.Register(r => new RecipeRepository<MongoSession>()).As<IRecipeRepository>().InstancePerLifetimeScope();
    builder.RegisterControllers(Assembly.GetExecutingAssembly());
 
    var container = builder.Build();
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
 
    AreaRegistration.RegisterAllAreas();
 
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

Finally, here is our controller.  Notice we never have to create a repository object - one was injected for us.

1
2
3
4
5
6
7
8
9
10
11
private readonly IRecipeRepository recipeRepository;
 
public RecipesController(IRecipeRepository recipeRepository)
{
    this.recipeRepository = recipeRepository;
}
 
public ViewResult Index()
{
    return View(recipeRepository.GetAll());
}

That's it.

Tagged as: 2 Comments
8Mar/112

A Diet and an Application

I've started on the Paleo Diet, which, of course, means I have to create a software application to go along with it.

I decided this was a good time to give MVC3 and MongoDB a test drive.  After diving in, I realized that I could benefit from some dependency injection via MVC3's DependencyResolver.  I've been wanting to learn Autofac, so I threw that in as the container.  This was sweet, as it injected my repository implementations into my controllers with very little setup.

At this point, I've learned all about the Razor view engine, DI with Autofac and DependencyResolver, MongoDB with the NoRM driver, jQuery, jQuery-ui, and some other MVC3 goodness.

For various reasons, including the fact that my web hosting provider is a Linux/non-ASP.NET provider, I ported the whole thing to Rails/MySql.  I'm glad I went through the MVC3 process, because I learned a lot, but in the end, Rails is just simpler.  As for MongoDB, and NoSQL in general, I think it's best served as an edge case storage medium for fast read operations.  Data is relational.

Alas, here is a screenshot of the recipe database.  I'll be adding lots of features, including menus and weight management.  You can't see it here, but it has a cool tag cloud feature and theme switching.

Recipes

Tagged as: 2 Comments