我必须在课程中深入到什么程度才能为 DI 正确连接温莎城堡?
是的,我是 Castle 的新手,我正在尝试弄清楚需要走多远才能连接服务。下面是我正在使用的类的示例以及它们在我创建的世界中的位置。
我正在尝试完成它以正确连接 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注册才能完全满足。
我必须在兔子洞里走多远才能把这个连线?此时,我正在查看 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.
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这些是我在您的代码中看到的问题:
container.AddComponent();
您需要在此处提供实现类,这就是您在解析时遇到异常的原因。
container.AddComponent();
如果您要注册没有接口的组件,则无需将实现类型重复为服务类型。
UsingFactory()
已过时。请改用UsingFactoryMethod()
。AddComponent()
已过时。请改用Register(Component.For...))
。UsingFactoryMethod()
。您需要注册您希望 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. UseUsingFactoryMethod()
instead.AddComponent()
is obsolete. UseRegister(Component.For...))
instead.UsingFactoryMethod()
.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.
我不完全理解你在这里所做的一切。最好从简单的开始,只使用几个类,然后逐步按照您想要的方式配置所有内容。您可能还想了解 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.