Using StructureMap to mock DataAccess in CSLA BO

I had always thought StructureMap is just another IOC tool similar to Castle windsor, until yesterday I read Karl Seguin’s Foundations of Programming, Chapter 4, I was shocked immediately by the injectStub method provided by StructureMap, which is now renamed to inject(). I think this explicitly injection is better than TypeMock implicitly mock instance object.

For example, I have an Organization BO,


public static OrganizationBO GetOrganizationBO(int Id)
{
return DataPortal.Fetch<OrganizationBO>(new SingleCriteria<OrganizationBO, int>(Id));
}

private void DataPortal_Fetch(SingleCriteria<OrganizationBO, int> criteria)
{
OrganizationDTO data = DataAccess.OrganizationRepository().FindById(criteria.Value);

if (data != null)
{
LoadFromDTO(data);
}
}

The repository is declared in DataAccess class to centralize all the dataaccess coupling inside CALS BOs.


public static IRepository<OrganizationDTO> OrganizationRepository()
{

// instead of direct coupling return new OrganizationRepository();
// I use StrcutureMap
return ObjectFactory.GetInstance<IRepository<OrganizationDTO>>();
}

The content of IOC config file:

<DefaultInstance
PluginType=”DemoApp.Data.Interfaces.IRepository`1,DemoApp.Data”    PluggedType=”DemoApp.Data.Repository.OrganizationRepository,DemoApp.Data”
/>

We can also use other different ways to set dependency, like setDefault in code, or search assembly at  runtime as shown in this post.

Test  code:


[Test]
public void CanGetFromInjectedMockRepository()
{
var mockRepository = new Moq.Mock<IRepository<OrganizationDTO>>();

// Id in MoQ matters. But TypeMock doesn't care.
mockRepository.Expect(x => x.FindById(8172)).Returns(
new OrganizationDTO
{
Id = 1,
Name = "A test org name"
});

ObjectFactory.Inject(typeof(IRepository<OrganizationDTO>), mockRepository.Object);

var o = OrganizationBO.GetOrganizationBO(8172);

Assert.AreEqual(1, o.Id);
Assert.AreEqual("A test org name", o.Name);
}

Here is an artile introducing StructureMap, as it mentioned, StrucutreMap is very good choice if you are working on a class has no “constructor injection”, CSLA is one of those!

I have the same feeling, as the author Karl Seguin said, constructor injection doesn’t really solve the extensibility problem; how does someone add(try to replace) a new plug-in without recompiling the entire application?

The problem/drawback to DI is also obvious, the xml config file keeps growing and expanding. The performance and mantiance will become an issue. That’s why Boo was inverted to save / speed up Castle Windsor. But what about structure Map?

Also I need tool / method to test this xml config file, see details here and here. Unfortunately, I couldn’t make this <structuremap.verification> task loaded into NAnt, (maybe this doesn’t exist in those two dlls at all? I can’t tell because NAnt loadTask doesn’t have output). I tried to different folders and also “Forced scan” using <loadtasks> command, neither one works. Thanks God, Jeremy does have another way to test config file,so called smock test:

ObjectFactory.AssertConfigurationIsValid();

Regarding unit-test and mock, I spent a lot time trying to figure out how to reset the default back. It turns out the documented ObjectFactory.resetdefault has been changed to reset.

About these ads

8 thoughts on “Using StructureMap to mock DataAccess in CSLA BO

    • I would like to do so, but the new version of CSLA introduced “ObjectFactory” which allows developers implement their own DataAccess layer. What I did here is an old fashion. Maybe this is still easier. I will try whenever I got time. Sorry about the possible delay.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s