使用Castle Windsor IoC注册通用类型和服务

时间:2010-08-01 11:08:51

标签: c# generics castle-windsor ioc-container configuration-files

再次问好stackoverflowians,

我认为现在是时候学习如何使用DI框架了。我听说过温莎城堡有很多好东西,所以我决定顺其自然。现在有关于如何使用它的大量教程,但是,我找不到有关Generics参与时该怎么做的有用信息。这是我的问题。

我有一个BaseDAO

namespace Utilities.DataAccess
{
    public class BaseDAO<T> : IBaseDAO<T>
    {
        public BaseDAO(IConnectionProvider _connectionProvider)
        {
           // Stuff
        }
    }
} 

我在这个上下文中对泛型有点新,我看到一些教程有一个没有泛型声明的'BaseDAO',只是它实现了泛型的接口。我已经在许多以前的项目中使用了上述方法(没有IoC),并且它对我来说很好......反正到了App.config!

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section
      name="castle"
      type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"></section>
  </configSections>

  <castle>
    <components>

      <component
        id="BaseDAO"
        service="Utilities.DataAccess.Interfaces.IBaseDAO`1, Utilities.DataAccess"
        type="Utilities.DataAccess.BaseDAO`1, Utilities.DataAccess" />

      <component
        id="NHibernateConnection"
        service="Utilities.DataAccess.ConnectionProviders.IConnectionProvider, Finchtils"
        type="Utilities.DataAccess.ConnectionProviders.NHibernateConnection" />

      <component
        id="XMLConnection"
        service="Utilities.DataAccess.ConnectionProviders.IConnectionProvider, Finchtils"
        type="Utilities.DataAccess.ConnectionProviders.XMLConnection, Utilities" />
    </components>
  </castle>
</configuration>

现在你们中的一些人可能已经想到了,这是一个实用工具库。我打算为我创建的每个项目使用这个程序集,这样我就不必编写相同的数据访问代码,这些代码在所有解决方案中保持不变。这样做的含义当然是我无法确切地告诉castle我将传递给BaseDAO的类型参数,在一个项目中它可能是Customer对象,另一个完全不同。我已经在其他论坛上看到这完全有可能,因为当你从容器中请求对象时,你可以指定类型然后就像;

BaseDAO<Customer> baseDao = container.Resolve<BaseDAO<Customer>>();

虽然这违反了我的设计工作,但我尝试在App.config

中使用以下表示法
<component
    id="BaseDAO"
    service="Utilities.DataAccess.Interfaces.IBaseDAO`1[[Utilities.DataInterface.IEntity]], Finchtills.DataAccess"
    type="Utilities.DataAccess.BaseDAO`1[[Utilities.DataInterface.IEntity]], Finchtils.DataAccess" />

但是,这也没有用,无论如何我都会收到以下错误:

Utilities.Testing.DataAccess.Unit.Testing_BaseDAO (TestFixtureSetUp):
System.Exception : The type name Utilities.DataAccess.BaseDAO`1, Utilities.DataAccess could not be located.
  ----> System.IO.FileNotFoundException : Could not load file or assembly 'Utilities.DataAccess' or one of its dependencies. The system cannot find the file specified.

阅读此错误,我认为它可能是两件事之一:

  1. 我在配置文件中遗漏了与类型和服务的泛型有关的内容。

  2. 我的名字不正确I.E是一个程序集名称。

  3. 我已将程序集名称视为项目所包含的项目,换句话说,在任何时候我都没有使用<solution name>.<project name>.<item folder>.<item name>但只是在项目级别启动...我假设任何配置选项都会知道从哪个解决方案调用它。

    感谢您提供有关此主题的任何帮助。

1 个答案:

答案 0 :(得分:1)

可以在Visual Studio中找到程序集名称:

  • 在解决方案资源管理器中,双击属性节点
  • 打开“应用程序”标签
  • 装配名称靠近右上角

或者,如果您在命令行进行编译,则使用/out参数。

此外,您需要为类型参数指定程序集(在方括号内)。因此,假设所有类型都在DataAccess程序集中,并且调用程序集(为简洁起见)“DataAccess”:

<component 
    id="BaseDAO"
    service="Utilities.DataAccess.Interfaces.IBaseDAO`1[[Utilities.DataInterface.IEntity, DataAccess]], DataAccess"
    type="Utilities.DataAccess.BaseDAO`1[[Utilities.DataInterface.IEntity, DataAccess]], DataAccess" /> 

但我同意其他评论者认为最好在代码中进行注册。您不必使用详细类型语法,并且您可以获得编译器检查类型。但是有一些缺点:很难判断你是否有未使用的类型,因为注册调用计为使用类型。