How to register subclass with xml?

Jul 14, 2012 at 1:37 PM
Edited Jul 14, 2012 at 2:37 PM

class A

{

public A(string a);

}

class B:A

{

public B():base("b");

}

class C

{

private B _b;

public C(B b)

{

_b=b;

}

}

how to register?

Is like normal?

tks!

Jul 15, 2012 at 7:15 AM

There is nothing special.  You just need to configure the container to supply the dependent constructor objects.

The only decision that you might want to think about when dealing with base classes and sub classes is how you want to register the sub classes?  You might want to register B as a named type of A depending on your design (although usually interfaces are used in these types of scenarios).

So the configuration would look like this:

    <container>
      <register type="ConsoleApplication1.A, ConsoleApplication1">
        <constructor>
          <param name="a" value="a"></param>
        </constructor>
      </register>
      <register type="ConsoleApplication1.A, ConsoleApplication1" mapTo="ConsoleApplication1.B, ConsoleApplication1" name="B">
      </register>
      <!-- Not required -->
      <register type="ConsoleApplication1.B, ConsoleApplication1">
      </register>
      <!-- Not required -->
      <register type="ConsoleApplication1.C, ConsoleApplication1">
      </register>
    </container>

Since we registered B as a named registration of type A we can do the following:

IUnityContainer container = new UnityContainer();
container.LoadConfiguration();
var a = container.Resolve<A>();
var b1 = container.Resolve<A>("B");
var b2 = container.Resolve<B>();
var c = container.Resolve<C>();

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

Jul 15, 2012 at 12:43 PM

I have send mail with minisrc to you with chicky0827@gmail.com

,It's not work well!

need you help,thank you!

Jul 15, 2012 at 3:46 PM

Based on the source you sent the issue is that you register the DbContext with name dbContext but when configuring the IGenericRepository you reference DbContext by the name "pianoContext".

      <register type="DbContext" mapTo="DbContext" name="dbContext">
        <constructor>
          <param name="nameOrConnectionString" type="System.String" value="pianoContext"></param>
        </constructor>
      </register>
      <register type ="IGenericRepository" mapTo="Repository" name="pianoRepository">
        <constructor>
          <param name="context">
            <dependency name="dbContext"/>
          </param>
        </constructor>
      </register>

In order to troubleshoot these issues you should start with the top level object you are trying to instantiate and then validate that every dependency is specified and that the names in the constructor param align with the names specified in another part of the configuration file.  Basically, you manually walk the object graph in your head.

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

Jul 16, 2012 at 4:42 AM

My first config file like this.but it not work ok.

throws exception:The entity type SysDepartment is not part of the model for the current context.

so I want to set pianocontext to repository because if I use pianoContext in repository it work ok!

if I set like this:

<alias alias="PianoContext" type="PianoEntities.Models.pianoContext,PianoEntities"/>

<register type="PianoContext" mapTo="PianoContext" name="pianoContext">
      </register>

<register type ="IGenericRepository" mapTo="Repository" name="pianoRepository">
        <constructor>
          <param name="context">
            <dependency name="pianoContext"/>
          </param>
        </constructor>
      </register>

throws exception:

 The type DbConnection cannot be constructed. You must configure the container to supply this value.

 

Jul 18, 2012 at 1:12 AM
I have replaied on codeplex.Is there any way to resolve it?

2012/7/17 randylevy <notifications@codeplex.com>

From: randylevy

Based on the source you sent the issue is that you register the DbContext with name dbContext but when configuring the IGenericRepository you reference DbContext by the name "pianoContext".

      <register type="DbContext" mapTo="DbContext" name="dbContext">
        <constructor>
          <param name="nameOrConnectionString" type="System.String" value="pianoContext"></param>
        </constructor>
      </register>
      <register type ="IGenericRepository" mapTo="Repository" name="pianoRepository">
        <constructor>
          <param name="context">
            <dependency name="dbContext"/>
          </param>
        </constructor>
      </register>

In order to troubleshoot these issues you should start with the top level object you are trying to instantiate and then validate that every dependency is specified and that the names in the constructor param align with the names specified in another part of the configuration file. Basically, you manually walk the object graph in your head.

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

Read the full discussion online.

To add a post to this discussion, reply to this email (unity@discussions.codeplex.com)

To start a new discussion for this project, email unity@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Jul 18, 2012 at 7:59 AM

The issue is with the UnitOfWork.  In the configuration file it is configured with dependency pianoContext:

 

      <register type="UnitOfWork" mapTo="UnitOfWork" name="unitOfWork">
        <constructor>
          <param name="ctx">
            <dependency name="pianoContext"/>
          </param>
        </constructor>
      </register>

      <register type="PianoContext" mapTo="PianoContext" name="pianoContext">
      </register>

 

The UnitOfWork constructor accepts a concrete DbContext but in the configuration file the UnitOfWork constructor accepts a pianoContext.   But a pianoContext is a DbContext.  Yes, but Unity is trying to lookup constructors on the concrete type and there is no DbContext configured with name pianoContext so it chooses the constructor with the most parameters and fails resolving the DbConnection.  So if you want to use the pianoContext class then change the pianoContext registration to:

 

      <register type="DbContext" mapTo="PianoContext" name="pianoContext">
      </register>

 

Now, when a DbContext is required with name pianoContext a pianoContext will be injected and everything should be fine.  The configuration should look like:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <configSections>
    <section name ="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
             Microsoft.Practices.Unity.Configuration"/>
  </configSections>

  <connectionStrings>
    <add name="pianoContext" connectionString="Data Source=AISINO-CHICKY;Initial Catalog=piano;Persist Security Info=True;User ID=sa;Password=cocoisxbs;MultipleActiveResultSets=True"
             providerName="System.Data.SqlClient" />
  </connectionStrings>

  <!--<appSettings>
    <add key="EntityFrameworkGenericRepository_ConnectionString" value="pianoContext"/>
  </appSettings>-->


  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
    <alias alias="external" type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager, Microsoft.Practices.Unity" />
    <alias alias="perThread" type="Microsoft.Practices.Unity.PerThreadLifetimeManager, Microsoft.Practices.Unity" />

    <alias alias="IGenericRepository" type="PianoDAL.Repository.Interfaces.IGenericRepository`1,PianoDAL"/>
    <alias alias="Repository" type="PianoDAL.Repository.Repositories.Repository`1,PianoDAL"/>
    <alias alias="UnitOfWork" type="PianoDAL.UnitOfWork.UnitOfWork,PianoDAL"/>
    <alias alias="DbContext" type="System.Data.Entity.DbContext,EntityFramework"/>
    <alias alias="PianoContext" type="PianoEntities.Models.pianoContext,PianoEntities"/>

    <alias alias="ISysUserService" type="PianoBusiness.SysManager.ISysUserService,PianoBusiness"/>
    <alias alias="SysUserService" type="PianoBusiness.SysManager.Impl.SysUserService,PianoBusiness"/>
    <alias alias="ISysDepartmentService" type="PianoBusiness.SysManager.ISysDepartmentService,PianoBusiness"/>
    <alias alias="SysDepartmentService" type="PianoBusiness.SysManager.Impl.SysDepartmentService,PianoBusiness"/>

    <container name="pianoContainer">
      <!--<register type="DbContext" mapTo="DbContext" name="dbContext">
        <constructor>
          <param name="nameOrConnectionString" type="System.String" value="pianoContext"></param>
        </constructor>
      </register>-->
      <register type="DbContext" mapTo="PianoContext" name="pianoContext">
      </register>
      <register type ="IGenericRepository" mapTo="Repository" name="pianoRepository">
        <constructor>
          <param name="context">
            <dependency name="pianoContext"/>
          </param>
        </constructor>
      </register>
      <register type="UnitOfWork" mapTo="UnitOfWork" name="unitOfWork">
        <constructor>
          <param name="ctx">
            <dependency name="pianoContext"/>
          </param>
        </constructor>
      </register>

      <register type="ISysUserService" mapTo="SysUserService" name="sysUserService">
        <constructor>
          <param name="sysUserDal">
            <dependency name="pianoRepository"></dependency>
          </param>
          <param name="unitOfWork">
            <dependency name="unitOfWork"></dependency>
          </param>
        </constructor>
      </register>
      <register type="ISysDepartmentService" mapTo="SysDepartmentService" name="sysDepartmentService">
        <constructor>
          <param name="sysDepartmentDal">
            <dependency name="pianoRepository"></dependency>
          </param>
          <param name="unitOfWork">
            <dependency name="unitOfWork"></dependency>
          </param>
        </constructor>
      </register>
    </container>
  </unity>
</configuration>

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

Jul 18, 2012 at 10:12 AM
It's working good!
thank you very much!!

2012/7/18 randylevy <notifications@codeplex.com>

From: randylevy

The issue is with the UnitOfWork. In the configuration file it is configured with dependency pianoContext:

      <register type="UnitOfWork" mapTo="UnitOfWork" name="unitOfWork">
        <constructor>
          <param name="ctx">
            <dependency name="pianoContext"/>
          </param>
        </constructor>
      </register>

      <register type="PianoContext" mapTo="PianoContext" name="pianoContext">
      </register>

The UnitOfWork constructor accepts a concrete DbContext but in the configuration file the UnitOfWork constructor accepts a pianoContext. But a pianoContext is a DbContext. Yes, but Unity is trying to lookup constructors on the concrete type and there is no DbContext configured with name pianoContext so it chooses the constructor with the most parameters and fails resolving the DbConnection. So if you want to use the pianoContext class then change the pianoContext registration to:

      <register type="DbContext" mapTo="PianoContext" name="pianoContext">
      </register>

Now, when a DbContext is required with name pianoContext a pianoContext will be injected and everything should be fine. The configuration should look like:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <configSections>
    <section name ="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
             Microsoft.Practices.Unity.Configuration"/>
  </configSections>

  <connectionStrings>
    <add name="pianoContext" connectionString="Data Source=AISINO-CHICKY;Initial Catalog=piano;Persist Security Info=True;User ID=sa;Password=cocoisxbs;MultipleActiveResultSets=True"
             providerName="System.Data.SqlClient" />
  </connectionStrings>

  <!--<appSettings>
    <add key="EntityFrameworkGenericRepository_ConnectionString" value="pianoContext"/>
  </appSettings>-->


  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
    <alias alias="external" type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager, Microsoft.Practices.Unity" />
    <alias alias="perThread" type="Microsoft.Practices.Unity.PerThreadLifetimeManager, Microsoft.Practices.Unity" />

    <alias alias="IGenericRepository" type="PianoDAL.Repository.Interfaces.IGenericRepository`1,PianoDAL"/>
    <alias alias="Repository" type="PianoDAL.Repository.Repositories.Repository`1,PianoDAL"/>
    <alias alias="UnitOfWork" type="PianoDAL.UnitOfWork.UnitOfWork,PianoDAL"/>
    <alias alias="DbContext" type="System.Data.Entity.DbContext,EntityFramework"/>
    <alias alias="PianoContext" type="PianoEntities.Models.pianoContext,PianoEntities"/>

    <alias alias="ISysUserService" type="PianoBusiness.SysManager.ISysUserService,PianoBusiness"/>
    <alias alias="SysUserService" type="PianoBusiness.SysManager.Impl.SysUserService,PianoBusiness"/>
    <alias alias="ISysDepartmentService" type="PianoBusiness.SysManager.ISysDepartmentService,PianoBusiness"/>
    <alias alias="SysDepartmentService" type="PianoBusiness.SysManager.Impl.SysDepartmentService,PianoBusiness"/>

    <container name="pianoContainer">
      <!--<register type="DbContext" mapTo="DbContext" name="dbContext">
        <constructor>
          <param name="nameOrConnectionString" type="System.String" value="pianoContext"></param>
        </constructor>
      </register>-->
      <register type="DbContext" mapTo="PianoContext" name="pianoContext">
</register> <register type ="IGenericRepository" mapTo="Repository" name="pianoRepository"> <constructor> <param name="context">
<dependency name="pianoContext"/> </param> </constructor> </register> <register type="UnitOfWork" mapTo="UnitOfWork" name="unitOfWork"> <constructor> <param name="ctx"> <dependency name="pianoContext"/> </param> </constructor> </register> <register type="ISysUserService" mapTo="SysUserService" name="sysUserService"> <constructor> <param name="sysUserDal"> <dependency name="pianoRepository"></dependency> </param> <param name="unitOfWork"> <dependency name="unitOfWork"></dependency> </param> </constructor> </register> <register type="ISysDepartmentService" mapTo="SysDepartmentService" name="sysDepartmentService"> <constructor> <param name="sysDepartmentDal"> <dependency name="pianoRepository"></dependency> </param> <param name="unitOfWork"> <dependency name="unitOfWork"></dependency> </param> </constructor> </register> </container> </unity> </configuration>

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

Read the full discussion online.

To add a post to this discussion, reply to this email (unity@discussions.codeplex.com)

To start a new discussion for this project, email unity@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com