Ash
Ash

Reputation: 5087

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:

Any suggestions welcome!

Upvotes: 0

Views: 205

Answers (5)

Ash
Ash

Reputation: 5087

In the end (given the constraints I was working within) I actually used a variation on a number of the themes above.

Because I had to avoid any references to my data access layer due to circular references occurring I ended up doing something with delegates and the 'factory' code. Fitting it into my original scenario I did the following:

class Car 
{
    public void SetLookupProvider(ILookupProvider value) { _lookupProvider = value; }

    public IMakeInfo Make { get { return _lookupProvider.ResolveMake(MakeId); } }

    ....
}

interface ILookupProvider
{
    IMakeInfo ResolveMake(int id);
}

class LookupProvider
{
    public delegate IMakeInfo ResolveMakeDelegate(int id);

    public ResolveMakeDelegate ResolveMakeDel { set { _resolvemake = value; } }

    public IMakeInfo ResolveMake(int id){ return _resolvemake(id); }  
}

Then in my factory method...

ICar returnedObject = new Car(blah, foo, bar, etc);

ILookupProvider luprovider = new LookupProvider();
luprovider.ResolveMakeDel = DataAccessLayer.FunctToGetMakeInfo;

(Car)returnedObject.SetLookupProvider(luprovider).

Now I'm the first to admit that this isn't the prettiest solution (I would have gone with Extension methods had I access to a 3.0 compiler..) but it does keep the Car class loosely coupled to the DataAccess layer (which in my situation prevented circular reference hell...). The Car class doesn't need to know how it is getting the result and the factory method which is producing the Car objects in the first place is the only thing which is coupled to the Data access layer.

I've not marked an answer yet, I'll let a few more people vote then go with the highest - particularly as I think they are all valid answers (its just that I couldn't use any one in entirety in this instance).

Upvotes: 0

Stobor
Stobor

Reputation: 45122

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.

Upvotes: 1

Matthew Flaschen
Matthew Flaschen

Reputation: 284786

Going with your analogy, the Car obviously needs to know by the time get_Make is called what the IMakeInfo is. I would also consider the make a key characteristic of the car. So I think passing a IMakeInfo to the Car constructor (possibly using IOC) is very reasonable. If this is a good analogy to your real code (each "Car" has a single, intrinsic, "IMakeInfo"), I would go with this.

You could also use a setter like Johan said, again with optional IOC. The reason I would prefer a constructor is that it seems every "Car" should have a "Make".

Upvotes: 0

Johan Leino
Johan Leino

Reputation: 3533

It sounds like Dependency Injection to me. I have done similar things with MS PP Unity and both contructor injection as well as method and property injection. Then your Car class would have some sort of injection of the IMakeInfo...example:

[InjectionMethod]
public void Initialize([Dependency] IMakeInfo makeInfo)
{
  this.MakeInfo = makeInfo;
}

Upvotes: 1

Mark
Mark

Reputation: 2432

Since the Car class has a property Make which returns IMakeInfo it looks like it already provides the information. So am I right in assuming that your problem is more how the car is provided with the value to return?

If this is the case perhaps you want to look at creating a factory method which knows about cars and ResolveMake.

Upvotes: 0

Related Questions