Why doesn't Unity support explicitly implemented interfaces

Aug 2, 2008 at 11:53 PM
When programming against an interface I prefer to implement the interfaces explicitly. The result is that the methods and properties are only available through the interface:

IFoo foo = new Foo() // where Foo implements IFoo explicitly.

In my opinion this is better a design than implementing the interfaces implicitly. This is what i call class automation (you generate proeprties and method skeletons via the Visual Studio IDE).

But I came to the conclusion that explicit implementation and dependency injection does not work. This makes Unity in my opinion useless (at least for property injection). I am not going to change my opinion on design principles because some framework dictates me tot do so.

My question is: is there a way to use explicitly implemented interfaces with Unity.

Jos Jansen
Aug 4, 2008 at 2:55 AM
Hi Jos,  the following is from the UnityContainerFixture.cs (Tests.Unity project):

        [TestMethod]
        public void CanBuildupObjectWithExplicitInterface()
        {
            IUnityContainer container = new UnityContainer()
                .RegisterType<ILogger, MockLogger>();

            ObjectWithExplicitInterface o = new ObjectWithExplicitInterface();
            container.BuildUp<ISomeCommonProperties>(o);

            o.ValidateInterface();
        }

        [TestMethod]
        public void CanBuildupObjectWithExplicitInterfaceUsingNongenericMethod()
        {
            IUnityContainer container = new UnityContainer()
                .RegisterType<ILogger, MockLogger>();

            ObjectWithExplicitInterface o = new ObjectWithExplicitInterface();
            container.BuildUp(typeof(ISomeCommonProperties), o);

            o.ValidateInterface();

        }

namespace Microsoft.Practices.Unity.Tests.TestObjects
{
    interface ISomeCommonProperties
    {
        [Dependency]
        ILogger Logger { get; set; }

        [Dependency]
        object SyncObject { get; set; }
    }

    class ObjectWithExplicitInterface : ISomeCommonProperties
    {
        private ILogger logger;
        private object syncObject;

        private object somethingElse;

        [Dependency]
        public object SomethingElse
        {
            get { return somethingElse; }
            set { somethingElse = value; }
        }

        [Dependency]
        ILogger ISomeCommonProperties.Logger
        {
            get { return logger; }
            set { logger = value; }
        }

        [Dependency]
        object ISomeCommonProperties.SyncObject
        {
            get { return syncObject; }
            set { syncObject = value; }
        }

        public void ValidateInterface()
        {
            Assert.IsNotNull(logger);
            Assert.IsNotNull(syncObject);
        }
    }
}


 

Aug 4, 2008 at 5:04 PM
Why did you come to this conclusion? General principles, or do you have a specific example that you tried that failed?

If the latter, please share with it us so we can fix it. Explicit interface implementation should just work.

Aug 4, 2008 at 10:53 PM
Like Chris I am confused as to why you think Unity doesn't work with explicit interface implementations. I agree with you completely on the principle and am using Unity with explicit interfaces to great effect. In fact, this is precisely why I requested that Unity support metamappings--so that the same class can implement multiple interfaces explicitly and have several interface mappings to the same concrete type. The only difficulty with the current Unity implementation is you have to define a separate mapping for each interface. That's a maintenance issue, though, not a show-stopper.

For example, the following works perfectly fine:

interface IFoo
{
void Foo();
}

interface IBar
{
void Bar();
}

class Baz : IFoo, IBar
{
void IFoo.Foo() { Debug.Print("foo"); }
void IBar.Bar() { Debug.Print("bar"); }
}

IUnityContainer container = new UnityContainer();
container.RegisterType<IFoo, Baz>();
container.RegisterType<IBar, Baz>();
IFoo foo = container.Resolve<IFoo>();
foo.Foo();
IBar bar = container.Resolve<IBar>();
bar.Bar();
Baz baz = bar as Baz;
Debug.Print(baz != null); // true
baz.Foo(); // Won't compile--implemented explicitly
baz.Bar(); // Won't compile--implemented explicitly
Aug 4, 2008 at 11:23 PM
Both examples work fine I see. I got it working in my project now thanks a lot.