Unity 2.0 - The injection configuration for property DataContext is specified through both attributes and child value elements

Apr 23, 2010 at 4:13 AM

Hi all,

I'm getting an error "The injection configuration for property DataContext is specified through both attributes and child value elements." for the following configuration 

<unity>

    <containers>
      <container>

        <!-- DataContext -->
        <register type="LoadMonster.Data.Model.LoadMonsterDataContext,LoadMonster.Data"
                  mapTo="LoadMonster.Data.Model.LoadMonsterDataContext,LoadMonster.Data"
                  name="LMDataContext">
          <lifetime type="singleton" />
          <constructor/>
        </register>

        <!-- Repositories -->
        <register type="LoadMonster.Data.Repository.IUserRepository,LoadMonster.Data"
                  mapTo="LoadMonster.Data.Repository.LinqToSql.LinqUserRepository,LoadMonster.Data.Repository.LinqToSql"
                  name="UserRepository">
          <lifetime type="singleton" />
          <property name="DataContext" propertyType="LoadMonster.Data.Model.LoadMonsterDataContext">
            <dependency name="LMDataContext" />
          </property>
        </register>

      </container>
    </containers>
  </unity>

This is with the 2.0 final release code. I can't seem to figure out why this is an issue but I'm a relative noob with Unity and it's entirely likely that it's user error.  Any help would be GREATLY appreciated.

Thanks,

Steve

Apr 23, 2010 at 7:01 AM

Looks like we've got a minor bug in there, but it's pretty harmless, just a bad error message. Remove the propertyType attribute, it's not needed anymore, we get the type right off the property now.

Also, you can change the property element to:

  <property name="DataContext" dependencyName="LMDataContext" />

Does the same thing, but a lot shorter. I'm writing this section of the docs right now.

 

 

Apr 23, 2010 at 5:01 PM

Thanks Ctavares!!! That's fixed that problem.  Now I seem to be having a different issue.  For some reason the properties aren't being injected.

The config is pretty straightforward:

  <unity>

    <containers>
      <container>

        <!-- DataContext -->
        <register type="LoadMonster.Data.Model.LoadMonsterDataContext,LoadMonster.Data"
                  mapTo="LoadMonster.Data.Model.LoadMonsterDataContext,LoadMonster.Data"
                  name="LMDataContext">
          <lifetime type="singleton" />
          <constructor/>
        </register>

        <!-- Repositories -->
        <register type="LoadMonster.Data.Repository.IUserRepository,LoadMonster.Data"
                  mapTo="LoadMonster.Data.Repository.LinqToSql.LinqUserRepository,LoadMonster.Data.Repository.LinqToSql"
                  name="UserRepository">
          <lifetime type="singleton" />
          <property name="DataContext" dependencyName="LMDataContext" />
        </register>

 

        <register type="LoadMonster.Service.Data.IUserService,LoadMonster.Service"
                  mapTo="LoadMonster.Service.Data.UserService,LoadMonster.Service"
                  name="UserServiceLM">
          <lifetime type="singleton" />
          <property name="Repository" dependencyName="UserRepository" />
        </register>

        <register type="System.Web.Mvc.IController,System.Web.Mvc"
                  mapTo="LoadMonster.Web.Controllers.DashboardController,LoadMonster.Web"
                  name="DashboardController">

          <property name="UserService" dependencyName="UserServiceLM" />

        </register>

      </container>
    </containers>
  </unity>

I'm resolving the DashboardController in ASP.NET MVC using this:

 

    public class UnityControllerFactory : IControllerFactory
    {    
        #region IControllerFactory Members     
        public IController CreateController(RequestContext requestContext, string controllerName)    
        {        
            var containerAccessor = requestContext.HttpContext.ApplicationInstance as IContainerAccessor;         
            var currentAssembly = Assembly.GetExecutingAssembly();        
            var controllerTypes = from t in currentAssembly.GetTypes()                              
                                  where t.Name.ToLower().Contains(controllerName.ToLower() + "controller")                              
                                  select t;
            IController result = null;
            if (controllerTypes.Count() > 0)        
            {
                if (containerAccessor != null)
                    result = containerAccessor.Container.Resolve(controllerTypes.First(), controllerName) as IController;
            }
            return result;   
        }     
        
        public void ReleaseController(IController controller)    
        {
        }     
        #endregion
    }

That's all good and the controller is resolved properly but when I get in to a method within the dashboard controller the UserService is null.

Any thoughts?


Steve

Apr 23, 2010 at 8:07 PM

 I think I see the issue. If I remember correctly, the controllerName you get from MVC doesn't actually container "Controller" at the end of it, so you'd just get "Dashboard". However, you've registered the controller in the config as "DashboardController". But when you resolve, you pass controllerName, which is just "Dashboard". Therefore the name you resolved doesn't match up with a name registered in the container, so the defaults kick in, which means no properties are injected.

Easiest fix would be to change the name in the config file to just "Dashboard". Also remember that registration names are case sensitive.

 

Apr 23, 2010 at 8:22 PM

Thanks SOO much.  That was exactly it.

I'm far more used to Spring on Java so a lot of this is un-learning. :)

Thanks again!!