1

Currently the structure of my application is as below Web App --> WCF Service (just a facade) --> Business Logic Services --> Repository -> Entity Framework Datacontext

Now each of my Business logic service is dependent on more than 5 repositories ( I have interfaces defined for all the repos) and I am doing a Constructor injection right now(poor mans DI instead of using a proper IOC as it was determined that it would be a overkill for our project). Repositories have references to EF datacontexts. Now some of the methods in the Business logic service require only one of the 5 repositories, so If I need to call that method I would end up instantiating a Service which will instatiate all 5 repositories which is a waste. An example:

public class SomeService : ISomeService
{
   public(IFirstRepository repo1, ISecondRepository repo2, IThirdRepository repo3)
   {}

   // My DoSomething method depends only on repo1 and doesn't use repo2 and repo3
   public DoSomething()
   {
        //uses repo1 to do some stuff, doesn't use repo2 and repo3
   }   

   public DoSomething2()
   {
     //uses repo2 and repo3 to do something, doesn't require repo1
   }

   public DoSomething3()
   {
     //uses repo3 to do something, doesn't require repo1 and repo2
   }
}

Now if my I have to use DoSomething method on SomeService I end up creating both IFirstRepository,ISecondRepository and IThirdRepository but using only IFirstRepository, now this is bugging me, I can seem to accept that I am un-necessarily creating repositories and not using them.

Is this a correct design? Are there any better alternatives? Should I be looking at Lazy instantiation Lazy<T> ?

  • If you know at the time you are creating your service what your repositories will be (and will never change) then in my opinion lazy instantiation is what you should do. – valenterry May 19 '14 at 18:51
  • 1
    Couple of links relating to moving away from UoW and repos: lostechies.com/jimmybogard/2012/10/08/… stackoverflow.com/questions/14110890/… – ozz May 19 '14 at 19:26
  • Unless your project is teeny-weeny, doing it properly won't take very long. Asking a question here about what to do instead probably took you longer. – Donal Fellows May 19 '14 at 19:41
  • 1
    @DonalFellows Well I wanted to know what is the proper way of doing it. – Sri Harsha Velicheti May 19 '14 at 20:08
1

ISP states:

no client should be forced to depend on methods it does not use

Although you are using all the methods from the 5 repositories, you are probably using them in different contexts and probably from different instances of the service (it's hard to figure out the usage scenario from the generic code sample you provided).

Also, your services seem to be doing more than one thing and should be broken down into smaller components (having 4 or more dependencies is often an indication of breaking SRP).

Advice: you should give DI a try. It's definitely not an overkill and you'll have some benefits out of it.

-1

I would pull each method of the service out into a Command, then use a DI container to instantiate the correct command with the correct parameters. By pulling each method into a command you no longer force separate commands to take on shared dependencies.

In practice your poor man's DI might look like:

public delegate T Factory<T>;

public class SomeService : ISomeService
{
   public(Factory<IFirstRepository> repo1Factory, /* ... */)
   {}

   // My DoSomething method depends only on repo1 and doesn't use repo2 and repo3
   public DoSomething()
   {
        //uses repo1 to do some stuff, doesn't use repo2 and repo3
       var handler = new DoSomethingHandler(repo1Factory());
       handler.Execute();
   }   

}
  • Programmers is tour conceptual questions and answers are expected to explain things. Throwing code dumps instead of explanation is like copying code from IDE to whiteboard: it may look familiar and even sometimes be understandable, but it feels weird... just weird. Whiteboard doesn't have compiler – gnat May 22 '14 at 8:34
  • 1
    Fair enough, I got sucked into the OP's code sample too quickly. I have reduced the sample code size and increased my explanation. – vanja May 22 '14 at 9:08
  • I don't really see the difference between your example and the question. Instead of injecting a bunch of repositories that may or may not get used, you're injecting a bunch of factories that may or may not get used... What's elided in your constructor sample is repo2Factory and repo3factory, making your class effectively equivalent. – Eric King Aug 20 '14 at 18:38
  • It's a stepping stone to a better solution. In my solution, the handlers now take in only the repositories they need. You are right that it still leaves a similar situation in the service layer, but it has reduced from many unrelated dependencies to just the dependencies required for this service (the handler factories). The next step would be to refactor the multiple handler factories in the service by using a service locator/dependency injection container. – vanja Sep 9 '14 at 12:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.