我必须在课程中深入到什么程度才能为 DI 正确连接温莎城堡?

发布于 2024-09-30 14:39:20 字数 4098 浏览 0 评论 0原文

是的,我是 Castle 的新手,我正在尝试弄清楚需要走多远才能连接服务。下面是我正在使用的类的示例以及它们在我创建的世界中的位置。

alt text

我正在尝试完成它以正确连接 Castle,以便我可以调用 TemplateEmailViaSalesforce 类来执行以下操作工作,并通过 Castle 的 DI 连接依赖类。但我不确定注册组件时需要走多远。下面是我的第一次尝试(我通过代码注册作为试用版,这是创建容器的几种方法的混搭)

IWindsorContainer container = new WindsorContainer();
        container.AddFacility<FactorySupportFacility>();

        // add the DAL mapper factory
        container.AddComponent<ITemplateMapperFactory>();

        // individual mappers
        container.Register(Component.For<ICSGEmailTemplateMapper>().UsingFactory((ITemplateMapperFactory f) => f.CSGEMailTemplate));
        container.Register(Component.For<IUserMapper>().UsingFactory((ITemplateMapperFactory f) => f.User));
        container.Register(Component.For<IGoupMapper>().UsingFactory((ITemplateMapperFactory f) => f.Group));
        container.Register(Component.For<IAccountTeamMapper>().UsingFactory((ITemplateMapperFactory f) => f.AccountTeam));
        container.Register(Component.For<ISalesTeamMapper>().UsingFactory((ITemplateMapperFactory f) => f.SalesTeam));
        container.Register(Component.For<ICSGFormulaMapper>().UsingFactory((ITemplateMapperFactory f) => f.CSGFormula));
        container.Register(Component.For<ISFObjectDefinitionMapper>().UsingFactory((ITemplateMapperFactory f) => f.SFDCObjectDefinition));
        container.Register(Component.For<ISFObjectValueMapper>().UsingFactory((ITemplateMapperFactory f) => f.SFDCObjectValue));
        container.Register(Component.For<ISalesforceTemplateMapper>().UsingFactory((ITemplateMapperFactory f) => f.Template));
        container.Register(Component.For<IRecipientMapper>().UsingFactory((ITemplateMapperFactory f) => f.Recipient));

        // BLL stuff (domain components)...general
        container.AddComponent<CSGEmailTemplateRepository, CSGEmailTemplateRepository>();
        container.AddComponent<RecipientRepository, RecipientRepository>();
        container.AddComponent<SFObjectDefinitionRepository, SFObjectDefinitionRepository>();
        container.AddComponent<SFObjectValueRepository, SFObjectValueRepository>();
        container.AddComponent<TemplateRepository, TemplateRepository>();
        container.AddComponent<UserRepository, UserRepository>();
        container.AddComponent<ITemplateService, TemplateService>();

        // specific for this action
        container.AddComponent<TemplateEmailerViaSalesforce>();
        container.AddComponent<TemplateParse>();

        // Aspects
        container.AddComponent<TraceAspect>();

现在,我稍后在以下位置收到错误: container.Resolve() ;

AssemblerTests.ShouldCreateTemplateService : FailedTest method Tests.AssemblerTests.ShouldCreateTemplateService threw exception:  Castle.MicroKernel.Facilities.FacilityException: You have specified a factory ('Castle.MicroKernel.Registration.GenericFactory`1[[CSG.Salesforce.TemplateEmailer.DAL.Access.IUserMapper, CSG.Salesforce.TemplateEmailer.DAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' - method to be called: Create) for the component 'CSG.Salesforce.TemplateEmailer.DAL.Access.IUserMapper' CSG.Salesforce.TemplateEmailer.DAL.Access.IUserMapper that failed during invoke. --->  System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. --->  Castle.MicroKernel.ComponentRegistrationException: Type CSG.Salesforce.TemplateEmailer.DAL.ITemplateMapperFactory is abstract.

失败似乎与 IUserMapper 相关,它被定义为 class UserMapper:BaseSalesforceMapper,IUserMapper

其他映射器可以工作,但我收到一个错误,表明并非所有依赖项都得到满足,我需要IUserMapper注册才能完全满足。

我必须在兔子洞里走多远才能把这个连线?此时,我正在查看 BLL 到 DAL 以及构建应用程序映射器的基类,但它似乎不正确。我正在努力弄清楚我必须注册什么以及 Castle 本身将用 DI 隐式完成什么。

任何帮助将不胜感激。谢谢。在此处输入代码

Right, so I'm new to Castle and I'm trying to figure out how far I need to go to wire up a service. Below is a sample of the classes I'm working with and where they sit in the world I've created.

alt text

What I'm trying to accomplish it to properly wire up Castle so that I can call the TemplateEmailViaSalesforce class to do the work, and have the dependent classes wired up via DI from Castle. But I'm unsure of how far I have to go when registering components. Below is my first attempt (I'm registering via code as a trial, and this is a mashup of a couple methods to create the container)

IWindsorContainer container = new WindsorContainer();
        container.AddFacility<FactorySupportFacility>();

        // add the DAL mapper factory
        container.AddComponent<ITemplateMapperFactory>();

        // individual mappers
        container.Register(Component.For<ICSGEmailTemplateMapper>().UsingFactory((ITemplateMapperFactory f) => f.CSGEMailTemplate));
        container.Register(Component.For<IUserMapper>().UsingFactory((ITemplateMapperFactory f) => f.User));
        container.Register(Component.For<IGoupMapper>().UsingFactory((ITemplateMapperFactory f) => f.Group));
        container.Register(Component.For<IAccountTeamMapper>().UsingFactory((ITemplateMapperFactory f) => f.AccountTeam));
        container.Register(Component.For<ISalesTeamMapper>().UsingFactory((ITemplateMapperFactory f) => f.SalesTeam));
        container.Register(Component.For<ICSGFormulaMapper>().UsingFactory((ITemplateMapperFactory f) => f.CSGFormula));
        container.Register(Component.For<ISFObjectDefinitionMapper>().UsingFactory((ITemplateMapperFactory f) => f.SFDCObjectDefinition));
        container.Register(Component.For<ISFObjectValueMapper>().UsingFactory((ITemplateMapperFactory f) => f.SFDCObjectValue));
        container.Register(Component.For<ISalesforceTemplateMapper>().UsingFactory((ITemplateMapperFactory f) => f.Template));
        container.Register(Component.For<IRecipientMapper>().UsingFactory((ITemplateMapperFactory f) => f.Recipient));

        // BLL stuff (domain components)...general
        container.AddComponent<CSGEmailTemplateRepository, CSGEmailTemplateRepository>();
        container.AddComponent<RecipientRepository, RecipientRepository>();
        container.AddComponent<SFObjectDefinitionRepository, SFObjectDefinitionRepository>();
        container.AddComponent<SFObjectValueRepository, SFObjectValueRepository>();
        container.AddComponent<TemplateRepository, TemplateRepository>();
        container.AddComponent<UserRepository, UserRepository>();
        container.AddComponent<ITemplateService, TemplateService>();

        // specific for this action
        container.AddComponent<TemplateEmailerViaSalesforce>();
        container.AddComponent<TemplateParse>();

        // Aspects
        container.AddComponent<TraceAspect>();

Now, I get an error later at: container.Resolve<TemplateEmailerViaSalesforce>();

AssemblerTests.ShouldCreateTemplateService : FailedTest method Tests.AssemblerTests.ShouldCreateTemplateService threw exception:  Castle.MicroKernel.Facilities.FacilityException: You have specified a factory ('Castle.MicroKernel.Registration.GenericFactory`1[[CSG.Salesforce.TemplateEmailer.DAL.Access.IUserMapper, CSG.Salesforce.TemplateEmailer.DAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' - method to be called: Create) for the component 'CSG.Salesforce.TemplateEmailer.DAL.Access.IUserMapper' CSG.Salesforce.TemplateEmailer.DAL.Access.IUserMapper that failed during invoke. --->  System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. --->  Castle.MicroKernel.ComponentRegistrationException: Type CSG.Salesforce.TemplateEmailer.DAL.ITemplateMapperFactory is abstract.

The failure seems to be with IUserMapper which is defined as class UserMapper:BaseSalesforceMapper<UserData>,IUserMapper

The other mappers work but I get an error that not all dependencies were satisfied, which I need the IUserMapper registration to satisfy fully.

How far down the rabbit hole do I have to go to get this wired? At this point I'm looking though the BLL into the DAL and into a base class that app mappers are built from and it doesn't seem right. I'm struggling with figuring out what I have to get registered and what will be implicitly done with DI by Castle itself.

Any help at all would be appreciated. Thanks.enter code here

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

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

发布评论

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

评论(2

吹泡泡o 2024-10-07 14:39:20

这些是我在您的代码中看到的问题:

  • container.AddComponent();

    您需要在此处提供实现类,这就是您在解析时遇到异常的原因。

  • container.AddComponent();

    如果您要注册没有接口的组件,则无需将实现类型重复为服务类型。

  • UsingFactory() 已过时。请改用 UsingFactoryMethod()

  • AddComponent() 已过时。请改用 Register(Component.For...))
  • 在最新版本的 Windsor 中,无需添加 FactorySupportFacility 即可使用 UsingFactoryMethod()

我必须注册什么以及 Castle 本身将使用 DI 隐式完成什么。

您需要注册您希望 Windsor 管理的每个组件。如果你不注册,温莎就不知道。不过,您可以设置约定以避免单独注册组件。 Windsor 为您所做的是隐式自动装配组件。

These are the issues I see in your code:

  • container.AddComponent<ITemplateMapperFactory>();

    you need to provide the implementation class here, this is the reason you're getting that exception when resolving.

  • container.AddComponent<UserRepository, UserRepository>();

    If you're registering a component without an interface there's no need to repeat the implementation type as service type.

  • UsingFactory() is obsolete. Use UsingFactoryMethod() instead.

  • AddComponent() is obsolete. Use Register(Component.For...)) instead.
  • In the latest version of Windsor there's no need to add the FactorySupportFacility to use UsingFactoryMethod().

what I have to get registered and what will be implicitly done with DI by Castle itself.

You need to register every component that you want Windsor to manage. If you don't register it, Windsor doesn't know about it. You can set up conventions to avoid registering components individually though. What Windsor does for you is auto-wire components implicitly.

天煞孤星 2024-10-07 14:39:20

我不完全理解你在这里所做的一切。最好从简单的开始,只使用几个类,然后逐步按照您想要的方式配置所有内容。您可能还想了解 Windsor 的自动装配——它至少应该使您的某些组件更易于配置。

尽管如此,在我看来,您正在指定一个用于工厂实现的接口(ITemplateMapperFactory)。正如错误消息所示:“ITemplateMapperFactory 是抽象的”。 Windsor 无法实例化无法实例化的东西。

免责声明:我不是工厂设施的专家,因为我不使用它。

I don't completely understand everything that you are doing here. It might be better to start simply, with just a few classes, and take baby steps to getting everything configured the way you want. You also might want to look at auto-wiring for Windsor--it should make at least some of your components easier to configure.

All that said, it looks to me like you are specifying an interface to use for your factory implementation (ITemplateMapperFactory). As the error message shows: "ITemplateMapperFactory is abstract". Windsor can't instantiate something that can't be instantiated.

Disclaimer: I'm not an expert on the factory facility, as I don't use it.

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