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

发布于 2024-09-12 07:30:55 字数 2935 浏览 0 评论 0原文

stackoverflowians 大家好,

我想是时候学习如何使用 DI 框架了。我听说过很多关于温莎城堡的好消息,所以我决定去那里。现在有很多关于如何使用它的教程,但是,我找不到太多关于涉及泛型时该怎么做的有用信息。这是我的问题。

我有一个 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. 我错误地命名了某个程序集名称。

我已将程序集名称视为项目所在的项目,换句话说,我从未使用过 <解决方案名称>.<项目名称>.<项目文件夹>.<项目名称> ; 但只是从项目级别开始...我假设任何配置选项都会知道它是从哪个解决方案中调用的。

感谢您就该主题提供的任何帮助。

Hello again stackoverflowians,

I thought it was about time that I learnt how to use a DI framework. 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

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. 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 !

<?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. 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

<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 I.E an assembly name.

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.

Thank you for any help you may be able to give on this subject.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉生梦死 2024-09-19 07:30:55

程序集名称可以在 Visual Studio 中找到,如下所示:

  • 在解决方案资源管理器中,双击属性节点
  • 打开“应用程序”选项卡 程序
  • 集名称位于右上角附近

或者,如果您在命令行进行编译,则可以使用 < code>/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" /> 

但我同意其他评论者的观点,即最好在代码中进行注册。首先,您不必使用详细的类型语法,并且编译器会检查您的类型。但是,也有一些缺点:很难判断是否有未使用的类型,因为注册调用被视为使用该类型。

The assembly name can be found in Visual Studio thus:

  • 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.

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":

<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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文