简体   繁体   English

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

[英]Registering generic types and services with Castle Windsor IoC

Hello again stackoverflowians, 您好,stackoverflowians,

I thought it was about time that I learnt how to use a DI framework. 我以为是时候学习了如何使用DI框架了。 I've heard a lot of good things about Castle Windsor so I decided to go with that. 我听说过许多关于温莎城堡的好事,所以我决定继续。 Now there are PLENTY of tutorials out there on how to use it, however, I cannot find much useful information about what to do when Generics get involved. 现在有很多关于如何使用它的教程,但是,我找不到有关泛型介入时该怎么做的有用信息。 Here is my issue. 这是我的问题。

I have a BaseDAO 我有一个BaseDAO

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

Im a little bit new to generics in this context and I have seen some tutorials which have a 'BaseDAO' with no generic declaration and simply the interface it implements with the generics on it. 在这种情况下,我对泛型有点陌生,我看到了一些教程,这些教程都有一个“ BaseDAO”,没有泛型声明,只是带有泛型的接口而已。 I have used the above way of doing things on many previous projects (without IoC) and its worked fine for me...anyways, onwards to the App.config ! 我已经在许多以前的项目(没有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>

Now as some of you may of figured by now, this is a utility library. 现在,正如您可能已经知道的那样,这是一个实用程序库。 I intend to use this assembly for each project I create so that I don't have to write the same data access code which remains the same across all solutions. 我打算将这个程序集用于我创建的每个项目,这样我就不必编写在所有解决方案中都相同的数据访问代码。 The implications of such of course is that I cannot tell castle exactly what type parameter I will pass to the BaseDAO, in one project it might be a Customer object, another entirely different. 当然,这样的含义是我无法确切地告诉城堡我将传递给BaseDAO的类型参数,在一个项目中,它可能是一个Customer对象,而另一个项目则完全不同。 I have read on other forums that this is entirely possible as when you request the object from the container you can specify the type then like; 我在其他论坛上已经读到,这完全有可能,因为当您从容器中请求对象时,您可以指定类型,然后按赞;

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

Although it is against my design efforts, I have tried to use the following notation in the App.config 尽管这与我的设计工作背道而驰,但我尝试在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" />

However, this has not worked either, in any case I get the following error: 但是,这也没有起作用,无论如何我都会遇到以下错误:

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.

Reading this error, I think it could be one of two things: 阅读此错误,我认为这可能是两件事之一:

  1. I am missing something from the config file to do with the generics of the types and services. 我在配置文件中缺少与类型和服务的泛型有关的内容。

  2. I have named something incorrectly IE an assembly name. 我已经错误地命名了IE的程序集名称。

I have treated the assembly name as the project that item is contained within, in other words, at no point have i used <solution name>.<project name>.<item folder>.<item name> but merely started at the project level...I assume that any config option would know what solution it is being called from. 我已经将程序集名称视为包含该项目的项目,换句话说,我从未使用过<solution name>.<project name>.<item folder>.<item name>而只是从项目开始级别...我假设任何配置选项都将知道从中调用什么解决方案。

Thank you for any help you may be able to give on this subject. 感谢您在这个问题上可能给予的帮助。

The assembly name can be found in Visual Studio thus: 程序集名称可以在Visual Studio中找到,因此:

  • In the solution explorer, double-click the properties node 在解决方案资源管理器中,双击“属性”节点
  • Open the Application tab 打开应用程序选项卡
  • Assembly name is near the top right corner 程序集名称在右上角附近

Or, if you're compiling at the command line, you use the /out argument. 或者,如果您在命令行编译,则使用/out参数。

Also, you need to specify the assembly for the type arguments (inside the square brackets). 另外,您需要为类型参数指定程序集(在方括号内)。 So, assuming all your types are in the DataAccess assembly, and that the assembly is called (for brevity's sake) "DataAccess": 因此,假设所有类型都在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" /> 

But I agree with other commenters that it's better to do the registrations in code. 但是我同意其他评论者的观点,最好以代码形式进行注册。 You don't have to use the verbose type syntax, for one, and you get compiler checking of your types. 您不必使用冗长的类型语法,就可以对类型进行编译器检查。 There are some disadvantages, however: it's harder to tell if you have unused types because the registration call counts as using the type. 但是,有一些缺点:很难确定您是否有未使用的类型,因为注册调用算作使用该类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM