0

I have an MVC project with the standard IoC setup that uses StructureMap to inject repositories into controller constructors.

I also decided I wanted to have a static "utilities" class where I could have common methods that can be called by different controllers. So for example, I have:

public static IEnumerable<CountryCode> GetCountryList()
{
    ICountryCodeRepository repo = ObjectFactory.GetInstance<ICountryCodeRepository>();
    IEnumerable<CountryCode> countries = repo.GetAll();
    return countries;
}

As you can see, that directly creates a repo object from the ObjectFactory. The problem, now, is that when I want to unit-test my controllers, I can mock the repos for the controllers, but not the repos in the utilities class (which the controller eventually calls) I'm sure there are other reasons why my utilities class is wrong, but this is what I see so far. I've also read some stuff saying what I have is bad design, I just don't know how to fix it.

I was thinking about having the GetCountryList() function to accept a repo object

GetCountryList(ICountryCodeRepository _repo)

and the calling controller would pass it in, but isn't that just creating another dependency concern because all controllers will have to know what the utility functions need?

Or is it possible to use StructureMap somehow to inject these utility methods?

Community
  • 1
  • 1
getit
  • 623
  • 2
  • 8
  • 30

1 Answers1

2

It's at least OK that you know that what you are doing is bad design. That's fine and people reading this post will know it as well and avoid doing the same mistake as you.

But now to the point, you could use a provider in your static class:

public static class Foo
{
    public static Func<ICountryCodeRepository> CountryRepoProvider = 
        () => ObjectFactory.GetInstance<ICountryCodeRepository>();

    public static IEnumerable<CountryCode> GetCountryList()
    {
        return CountryRepoProvider().GetAll();
    }
}

and now in your unit test you could mock it:

Foo.CountryRepoProvider = () => mocha; 

or if you are using ASP.NET MVC 3 and you DI framework uses a dependency resolver you could improve this code by at least making it DI framework agnostic:

public static IEnumerable<CountryCode> GetCountryList()
{
    var repo = DependencyResolver.Current.GetService<ICountryCodeRepository>();
    return repo.GetAll();
}

Now in your unit test you could of course write a custom dependency resolver which will spit mocked instances of your services.

And now when you look at this code you might really say to yourself: What am I doing? I am writing a static class with one liner methods delegating to a repository I am fetching from the DI. What's the point when I can benefit from my DI framework to directly inject the instance of this repository wherever I need it and then simply call the method I need on it? What am I unit testing in those one liner static methods? Why am I wasting my time.

And if of course you had more complex logic to handle you would simply write a service layer which will take the necessary repositories as constructor dependencies and perform the complex business operations on them. Then you will simply configure your DI framework to inject those ready to be used instance of the service in your controllers or wherever you need it. See? No need of any static class. Weak coupling and unit testing friendly code.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Thanks for the help. Most of what you suggested confuses and scares me...but regarding your last 2 paragraphs: The reason I have these one-liner things is because I just don't want the controllers to have to know where these lists come from. Like, now they are coming from a DB call, but they could just as easily come from a file. I think the only solution I have is to turn this into a service layer type class. I just don't know how to use DI with it. My controller will have to call this new service class, so won't it be the controller making the repo object and not the DI framework? – getit Jun 28 '12 at 17:15