Search code examples
c#design-patterns.net-2.0loose-coupling

Any suitable patterns for this problem?


I have a situation in which I am attempting to keep my model and implementation as loosely coupled as possible, however I am faced with a situation where the coupling could potentially get a lot closer than I want.

I have a selection of 'Model' classes, all implementing interfaces. Additionally I have 'Data Access' classes, which provide a number of functions, one of which is decoding integer lookup values into their full 'object' representation.

Within my model classes I want to provide access to these decoded values without requiring the model to know about the data access classes.

A simplified example is:

/// Core classes --

class Car : ICar
{
    public int MakeId { get {...} set { ... } }

    public IMakeInfo Make { get {...} }

    public string Registration { get { ... } set { ... } }

    public int CurrentOwnerId { get { ... } set { ... } }

    public IPerson CurrentOwner { get { ... } }
}

class MakeInfo : IMakeInfo
{
    public string Name { ... }
    public int Id { ... }
    public decimal Weight { ... }
    // etc etc
}

/// Data Access Classes --

class ResolveMake 
{
    public IMakeInfo GetMakeInfo(int id)
    { 
        // Implementation here...
    }

}

How do I enable the Car class to provide the IMakeInfo object to any consuming classes without directly making it aware of the ResolveMake class? In the actual instance I am working with the Car class is not in the same namespace as the ResolveMake class and it contains no references to any instances of it.

Some of my options:

  • Implement a delegate in Car which can be supplied with an instance of the GetMakeInfo method.
  • Some kind of dependency injection
  • Closely couple Car to ResolveMake and be done with it.
  • Any other options?

Any suggestions welcome!


Solution

  • Extension Methods?

    namespace CarStuff
    {
       class Car : ICar
       {
          public int MakeId { get {...} set { ... } }
          // no Make property...
          public string Registration { get { ... } set { ... } }
          public int CurrentOwnerId { get { ... } set { ... } }
          public IPerson CurrentOwner { get { ... } }
       }
    }
    
    
    namespace MakeExts
    {
       class ResolveMake
       {
          public static IMakeInfo Make(this Car myCar)
          {
             //implementation here
          }
       }
    }
    

    elsewhere:

    using MakeExts;
    
    Car c = new Car();
    Console.WriteLine(c.Make().ToString());
    

    Edit: For using Extension Methods in .NET 2.0, you need something like:

    Basically, a class containing:

    namespace System.Runtime.CompilerServices 
    { 
       class ExtensionAttribute : Attribute
       {
       }
     }
    

    and a "using System.Runtime.CompilerServices" scattered in relevant places.