Exception is: InvalidOperationException - The type IBusinessDataManager does not have an accessible constructor.

Topics: General discussion, Policy Injection Application Block
Sep 24, 2013 at 3:28 PM
Edited Sep 24, 2013 at 4:02 PM
Hello,

I have this error:

Resolution of the dependency failed, type = "RetailerDataImport.Contracts.RetailerBase", name = "MyRetailer".

Exception occurred while: while resolving.

Exception is: InvalidOperationException - The type IBusinessDataManager does not have an accessible constructor.

At the time of the exception, the container was:

Resolving Retailer.MyRetailer, MyRetailer (mapped from RetailerDataImport.Contracts.RetailerBase, MyRetailer)

Resolving parameter "businessDataManager" of constructor Retailer.MyRetailer(RetailerDataImport.Contracts.IBusinessDataManager businessDataManager)

Resolving RetailerDataImport.Contracts.IBusinessDataManager,(none)



How can I solve it? Down my code.


My App.Config file have this section
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias alias="IBusinessDataManager"  type="RetailerDataImport.Contracts.IBusinessDataManager, RetailerDataImportContracts"/>

    <alias alias="RetailerBase" type="RetailerDataImport.Contracts.RetailerBase, RetailerDataImportContracts"/>
    <container>
        <register type="IBusinessDataManager" mapTo="RetailerDataImport.BusinessObjects.DataAccessManager, RetailerDataImportBusinessObjects" name="MyBDM">
            <lifetime type="singleton"/>
        </register>

        <register type="RetailerDataImport.Contracts.RetailerBase, RetailerDataImportContracts" mapTo="Retailer.MyRetailer, MyRetailer" name="MyRetailer" >
            <lifetime type="singleton"/>
            <constructor>
                <param name="businessDataManager" type="IBusinessDataManager">
                    <dependency/>
                </param>
            </constructor>
        </register>
    </container>
</unity>
and my Program class this code:
namespace RetailerDataImportEnterpriceLibrary
{
    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer container = new UnityContainer();
            container.LoadConfiguration();
            
            IBusinessDataManager ibdm = container.Resolve<IBusinessDataManager>("MyBDM");

            var retailers = (container.ResolveAll<RetailerBase>()).ToList(); //with this row ERROR!!!
        }
    }
interface and other classes:
namespace RetailerDataImport.Contracts
{
public interface IBusinessDataManager
    {
        void Test();
    }
}

namespace RetailerDataImport.BusinessObjects
{
    public class DataAccessManager : IBusinessDataManager
    {
        public DataAccessManager()
        {
        }

        public Test()
        {
            //Do something
        }
    }
}
RetailerBase class with IRetailer black interface:
using System.Xml;
using System.Xml.Serialization;
using RetailerDataImport.Contracts;
using Microsoft.Practices.Unity;

namespace RetailerDataImport.Contracts
{
    public abstract class RetailerBase : IRetailer
    {
        public IBusinessDataManager BusinessDataManager { get; set; }

        public string Name { get; set; }
        
        public RetailerBase(IBusinessDataManager businessDataManager)
        {
            BusinessDataManager = businessDataManager;
        }

        public string WhoIAm
        {
            get
            {   return string.Format("Sono il Retailer: {0}", Name);    }
        }
    }
}
Retailer class:
using RetailerDataImport.Contracts;

namespace Retailer
{
    public class MyRetailer : RetailerBase
    {
        public MyRetailer(IBusinessDataManager businessDataManager)
            : base(businessDataManager)
        {
            Name = "MyRetailer TEST Constructor Injection";
        }
    }
}
Thanks in advance
Luca Jonathan Panetta
Sep 25, 2013 at 6:13 AM
Edited Sep 25, 2013 at 6:16 AM
Thanks for posting your code and configuration -- it makes giving a good answer much easier.

RetailerBase only has one constructor which accepts an IBusinessDataManager. There is an IBusinessDataManager defined in the config but it is a named registration. When you register RetailerBase like this:
<register type="RetailerDataImport.Contracts.RetailerBase, RetailerDataImportContracts" mapTo="Retailer.MyRetailer, MyRetailer" name="MyRetailer" >
  <lifetime type="singleton"/>
  <constructor>
    <param name="businessDataManager" type="IBusinessDataManager">
      <dependency/>
    </param>
  </constructor>
</register>
This tells Unity to use the resolve the default IBusinessDataManager. However there is no default registration for this interface so an exception is thrown. If you want to use the already configured IBusinessDataManager registration named "MyBDM" then you can indicate that in the dependency element:
<register type="RetailerDataImport.Contracts.RetailerBase, RetailerDataImportContracts" mapTo="Retailer.MyRetailer, MyRetailer" name="MyRetailer" >
  <lifetime type="singleton"/>
  <constructor>
    <param name="businessDataManager" type="IBusinessDataManager">
      <dependency name="MyBDM" />
    </param>
  </constructor>
</register>

If you want to use the default registration then you will need to create one for IBusinessDataManager (but since IBusinessDataManager is a singleton I'm guessing that isn't what you want).

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Sep 25, 2013 at 9:25 AM
Edited Sep 25, 2013 at 9:43 AM
Thank you so much Randy for your answer.

Please can you show me how to use PropertyInjection too?

In possible to activate the intellisense for unity in app.config to help me to write the config section for unity?

Thanks in advance
Luca Jonathan Panetta
http://www.pljsoftware.com
Sep 26, 2013 at 7:32 AM
You can inject properties using the XML configuration:
<register type="RetailerDataImport.Contracts.RetailerBase, RetailerDataImportContracts" mapTo="Retailer.MyRetailer, MyRetailer" name="MyRetailer" >
  <lifetime type="singleton"/>
  <constructor>
    <param name="businessDataManager" type="IBusinessDataManager">
      <dependency name="MyBDM" />
    </param>
  </constructor>
  <property name="Name" value="Bob" />
</register>

You can add the Unity Schema (it's downloaded with the binaries from NuGet) to the Visual Studio schema cache. See How to: Select the XML Schemas to Use.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to