Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Injecting an interface into unrelated types via partial classes

0.00/5 (No votes)
20 Nov 2017 1  
This how-to article explores an approach using partial classes to inject a common interface into unrelated types that are auto-generated from web services or other external sources

Introduction

Recently I was working on some code that was pulling data objects off a remote WCF OAuth API. Visual Studio auto-generated the proxy classes for the data entities, and it was all good. There was one glitch though. While the various entity classes had several common properties such as IsDeleted, IsActive, etc. they did not share a base class or interface. So while we had methods that looped through these objects and did pretty much identical tasks against these properties, we could not use a common method as these were seemingly unrelated classes. Luckily, they were all partial classes, which meant we could use that to inject a common base interface to these classes. This article describes this approach.

Example code

This is a dumbed down example, so it will seem rather contrived. Use your imagination to transform this to a more realistic scenario.

namespace LibraryY
{
    public partial class ObjectY
    {
        public bool IsDeleted { get; set; }

        public bool IsDisabled { get; set; }

        public bool IsInActive { get; set; }

        public static ICollection<ObjectY> GetItems()
        {
            return new[] { new ObjectY() };
        }
    }
}

And here's a second unrelated class with no common base interface or class. Even in a different namespace.

namespace LibraryX
{
    public partial class ObjectX
    {
        public bool IsDeleted { get; set; }

        public bool IsDisabled { get; set; }

        public bool InActive { get; set; }

        public static ICollection<ObjectY> GetItems()
        {
            return new[] { new ObjectX() };
        }
    }
}

Notice how they have two properties that have identical names.

  • IsDeleted
  • IsDisabled

They also have a property each, which represents the same logical meaning but are named differently

  • ObjectX.InActive
  • ObjectY.IsInActive

The partial class trick works for the first scenario, same names. For the different-names scenario, I discuss a different approach for the sake of completion. But that's not set in stone, so you may have other preferred workarounds.

Injecting the interface

Essentially, there are two steps here. Step 1 is to define an interface with the commonly named properties.

namespace InterfaceInjector
{
    interface ICommonInterface
    {
        bool IsDeleted { get; set; }
        bool IsDisabled { get; set; }
    }
}

And step 2 is to use partial classes to extend the unrelated classes and apply this interface

namespace LibraryX
{
    public partial class ObjectX : InterfaceInjector.ICommonInterface { }
}

namespace LibraryY
{
    public partial class ObjectY : InterfaceInjector.ICommonInterface { }
}

That's it, really. Here's some test code showing this in action

    var xItems = LibraryX.ObjectX.GetItems();

    foreach (var item in xItems)
    {
        Handle(item);
    }

    var yItems = LibraryY.ObjectY.GetItems();

    foreach (var item in yItems)
    {
        Handle(item);
    }

// . . . 

private static void Handle(InterfaceInjector.ICommonInterface item)
{
    if(item.IsDeleted)
    {
        // handle delete
    }

    if(item.IsDisabled)
    {
        // handle disable
    }
}

So, we have a common shared method processing objects that are unrelated. Well, techncially we've forced them to be in a sort of relationship here. Alright, so what about the other scenario? As mentioned, you can do this is multiple ways, and here's one easy way to do this. This approach defines a wrapper class per differently named property in the unrelated classes that all work the same way logically (this is for you to ascertain).

interface IActiveStatus
{
    bool IsInActive { get; set; }
}

public class ActiveStatusWrapper<T> : IActiveStatus
{
    T item;
    Func<bool> getter;
    Action<bool> setter;

    public ActiveStatusWrapper(T item, Func<bool> getter, Action<bool> setter)
    {
        this.item = item;
        this.getter = getter;
        this.setter = setter;
    }

    public bool IsInActive
    {
        get
        {
            return getter();
        }

        set
        {
            setter(value);
        }
    }

    public T Item { get { return item; } }
}

Now you would just need to define a method to handle this new interface.

private static void Handle(IActiveStatus activeStatusItem)
{
    if(activeStatusItem.IsInActive)
    {
        // handle inactive
    }
}

When passing the objects to the method, create an instance of the wrapper and pass the getter/setter methods.

var xItems = LibraryX.ObjectX.GetItems();

foreach (var item in xItems)
{
    Handle(item);
    Handle(new ActiveStatusWrapper<ObjectX>(item, 
        () => item.InActive, (v) => item.InActive = v));        
}

var yItems = LibraryY.ObjectY.GetItems();

foreach (var item in yItems)
{
    Handle(item);
    Handle(new ActiveStatusWrapper<ObjectY>(item, 
        () => item.IsInActive, (v) => item.IsInActive = v));
}

You can clean this up a little better by using reflection to invoke the getter/setter methods. That way you don't need to instantiate function and action objects for each object. That said, compared with the additional cost of relection, you may want to compare the two approaches for performance before making a call there.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here