Resolving the dependency defined in an interface

Sep 23, 2008 at 3:32 AM
Edited Sep 23, 2008 at 3:35 AM
Hi,

This may be a basic question. Here is what I want to do:
I have an inteface, IRepository, where I want to have my connectionString injected:

 

public interface IRepository
{
    [Dependency("ConnectionString")]
    string ConnectionString { set; }
}

And there are classes that implement this interface; for example, CustomerRepository.

Is it possible to have the dependency attribute in the interface instead of adding it to all the derived classes?

Apr 5, 2012 at 4:37 PM

I realize this post is 4 years old, but no responses!

I'm interesting in doing exactly the same thing.

In my simple testing it appears the dependency attribute only works on the concrete implementation?

Apr 8, 2012 at 9:12 AM
Edited Apr 8, 2012 at 9:13 PM

Yes, the dependency attribute is only applied against classes and not interfaces.  I believe Unity mainly uses the interfaces for the type mappings and not for factories.

You can use a UnityContainerExtension to create the desired behavior.  For the specific scenario above something like this should work:

    public class InterfacePropertyContainerExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            base.Context.Registering += new EventHandler<RegisterEventArgs>(this.OnRegister);
        }

        private void OnRegister(object sender, RegisterEventArgs e)
        {
            IUnityContainer container = sender as IUnityContainer;

            if (e.TypeFrom.IsInterface)
            {
                foreach (PropertyInfo property in e.TypeFrom.GetProperties())
                {
                    foreach (var attribute in property.GetCustomAttributes(typeof(DependencyAttribute), false))
                    {
                        var depAttr = attribute as DependencyAttribute;

                        InjectionProperty iProp =
                            new InjectionProperty(depAttr.Name, 
                                container.Resolve(property.PropertyType, depAttr.Name));
 
                        iProp.AddPolicies(e.TypeTo, base.Context.Policies); 
                    }
                }
            }
        }
    }

Then you can resolve the CustomerRepository with the ConnectionString injected:

    var container = new UnityContainer();
    container.AddNewExtension<InterfacePropertyContainerExtension>();

    container.RegisterInstance<string>("ConnectionString", "ABC");
    container.RegisterType<IRepository, CustomerRepository>();
    var repository = container.Resolve<IRepository>();

Now this is a simple example for the specific scenario above so probably doesn't cover every possible requirement but hopefully can help (if you want to go this route).

An alternative would be to create an abstract base class that implements the interface and have the concrete classes extend the abstract base class instead of implementing the interface.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com