Unity 2.0 registering generic types via XML

2019-01-17 18:10发布

问题:

I am trying to register a generic type in a config file for Unity 2.0 but can't seem to get it right. I have been referring to the MS documentation here : http://msdn.microsoft.com/en-us/library/ff660933%28v=PandP.20%29.aspx#_Generic_Types

The code looks like this:

public interface IRepository<T> where T : class
{
    ...
}

public class GenericRepository<T> : IRepository<T> where T : class
{
    ...
}

public class BlogRepository : GenericRepository<BlogRepository>
{
    ...
}

The XML config i have at the moment loks like this:

<unity>
    <!-- Aliases -->
    <alias alias="BlogIRepository" 
           type="X.Services.Interfaces.IRepository[[X.Domain.Entities.Blog, X.Domain]], X.Services"/>

    <alias alias="BlogRepository" 
           type="X.Repositories.BlogRepository, X.Repositories"/>

    <!-- Type registration -->
    <container name="development">
        <!-- Common connection string value -->
        <instance name="Conn" type="System.String" value="blahblahblah"/>
        <register type="BlogIRepository" mapTo="BlogRepository">
            <constructor>
                <param name="connectionString" type="System.String" dependencyName="Conn"/>
            </constructor>
        </register>
    </container>
</unity>

According to the documentation to register generic types you use square brackets around the generic type(s), and if the type is not a system type you provide the fully qualified type inside more square bracket. Which is what i have done, i think. Yet - no worky.

EDIT: Example from the MSDN site:

<register type="IDictionary[string, [MyApp.Interfaces.ILogger, MyApp]]"/>

The error generated is:

The type name or alias IRepository could not be resolved. Please check your configuration file and verify this type name.

回答1:

MSDN is NOT wrong. We specifically added some shortcut parsing rules so that you don't have to enter all the `'s and square brackets in most cases.

I slapped together an example that looks mostly like yours:

public interface IRepository<T> where T: class
{

}

public class GenericRepository<T> : IRepository<T> where T : class
{

}

public class BlogRepository : GenericRepository<Blog>
{

}

public class Blog
{

}

My XML config looks like this:

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <namespace name="UnityConfigExample"/>
    <assembly name="UnityConfigExample"/>

    <container>
      <register type="IRepository[]" mapTo="GenericRepository[]" />
      <register type="IRepository[Blog]" mapTo="BlogRepository" />
    </container>
  </unity>

and it just works.

Were you by any chance trying to use an alias for IRepository instead of the namespace / assembly search? I got the following to work as well using aliases:

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias alias="IRepository" type="UnityConfigExample.IRepository`1, UnityConfigExample" />
    <alias alias="GenericRepository" type="UnityConfigExample.GenericRepository`1, UnityConfigExample"/>
    <alias alias="BlogRepository" type="UnityConfigExample.BlogRepository, UnityConfigExample"/>
    <alias alias="Blog" type="UnityConfigExample.BlogRepository, UnityConfigExample"/>

    <container>
      <register type="IRepository[]" mapTo="GenericRepository[]" />
      <register type="IRepository[Blog]" mapTo="BlogRepository" />
    </container>
  </unity>

When you specify the type for an alias, you must use the CLR type syntax. Everywhere else you can use the generic shortcut syntax.



回答2:

you're missing a ` character before [[ (below Esc on my keyboard)



回答3:

I think you need to add `1, as the examples here on MSDN would suggest:

type="X.Services.Interfaces.IRepository`1[[X.Domain.Entities.Blog, X.Domain]], X.Services"