gpt4 book ai didi

asp.net-mvc - 使用基类的参数解析构造函数参数

转载 作者:行者123 更新时间:2023-12-04 23:55:44 25 4
gpt4 key购买 nike

我有一个自定义的 ASP.NET MVC Controller ,它从用户服务中检索操作。我想使用依赖注入(inject)将操作属性传递给场景服务。

public abstract class BaseController : Controller {
protected IUserService userService;
public OperationWrapper operations { get; private set; }
public BaseController(IUserService userService) {
this.userService = userService;
this.operations = userService.GetOperations(HttpContext.Current.User.Identity.Name);
}
}

public abstract class ScenarioController : BaseController {
protected IScenarioService scenarioService;
public ScenarioController(IScenarioService scenarioService, IUserService userService)
: base(userService) {
this.scenarioService = scenarioService;
}
}

public class ScenarioService : IScenarioService {
private OperationWrapper operations;
public ScenarioService(OperationWrapper operations) {
this.repo = repo;
this.operations = operations;
}
}

这是我的温莎安装程序。

public class Installer : IWindsorInstaller {
public void Install(IWindsorContainer container, IConfigurationStore store) {
container.Register(Classes.FromThisAssembly()
.BasedOn<IController>());

container.Register(Classes.FromThisAssembly()
.Where(x => x.Name.EndsWith("Service"))
.WithService.DefaultInterfaces()
.LifestyleTransient());
}
}

我很确定几年前我用 Ninject 做过类似的事情。我需要在安装程序中添加什么才能使其正常工作?有可能吗?

最佳答案

这里有几个选项:

1。使用 LifeStylePerWebRequest()UsingFactoryMethod()

首先,您可以将 OperationWrapper 注册为 LifestylePerWebRequest()并将其注入(inject)到 BaseControllerScenarioService 中。 Windsor 将允许您使用用于创建它的工厂方法注册依赖项,该方法可以依次调用已注册的其他服务。

container.Register(Component.For<OperationWrapper>()
.LifestylePerWebRequest()
.UsingFactoryMethod(kernel =>
{
var userService = kernel.Resolve<IUserService>();
try
{
return userService.GetOperations(
HttpContext.Current.User.Identity.Name);
}
finally
{
kernel.ReleaseComponent(userService);
}
}));

因此,每次要求 Windsor 提供 OperationWrapper 时,它都会针对 IUserService 实例运行该调用,并为其指定 Name当前用户。通过将生活方式绑定(bind)到 LifestylePerWebRequest(),您可以验证每个请求都将获得其自己的 OperationWrapper 实例,并且不会跨请求流血。

(您遇到的唯一边缘情况是用户在请求中通过身份验证,因此需要调整 OperationWrapper。如果这是正常路径用例,这可能需要重新考虑。)

然后,修改您的基础 Controller 以将该注册对象作为依赖项:

public abstract class BaseController : Controller {
protected IUserService userService;
protected OperationWrapper operations;
public BaseController(IUserService userService, OperationWrapper operations) {
this.userService = userService;
this.operations = operations;
}
}

2。使用方法注入(inject)

看起来 OperationWrapper 是某种上下文对象,有时可以将它们注入(inject)到方法中而不是注入(inject)到构造函数中。

例如,如果您的方法是:

int GetTransactionId() { /* use OperationWrapper property */ }

您可以将签名修改为如下所示:

int GetTransactionId(OperationWrapper operations) { /* use arg */ }

在这种情况下,如果您的服务方法的一小部分使用该依赖项,则使用它是有意义的。如果大多数(或全部)方法需要它,那么您可能应该走不同的路线。

3。根本不要将 DI 用于 OperationWrapper

在您有一个高度有状态的上下文对象(看起来像您的 OperationWrapper)的情况下,拥有一个其值被传递的属性通常是有意义的。由于该对象基于某些当前线程状态,并且可以从任何子类 Controller 中的任何位置访问,因此正确只保留您拥有的模式可能是正确的。

如果您无法回答“既然 DI 将为我解决问题,我无法使用 OperationWrapper 做什么?”除了“使用模式/容器”之外,这可能是针对这种特定情况的选择。

关于asp.net-mvc - 使用基类的参数解析构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31371570/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com