gpt4 book ai didi

c# - 结构图 IContainer 实现

转载 作者:行者123 更新时间:2023-12-01 19:39:34 25 4
gpt4 key购买 nike

既然 ObjectFactory 静态函数已被标记为过时,我目前正在尝试了解结构图。

从长远来看,我必须在 MVC 和 WebApi 应用程序中使用它。以前使用时,静态方法的一行被放置在 global.asax 中,以使用 ObjectFactory 初始化所有内容。

 ObjectFactory.Initialize{
container.For .....
}

尝试将其转换为新的 IContainer 方法,我提出了以下方法,但我想知道我是否实际上无意中在我的方法中实现了这种经常提到的反模式。

返回容器的静态方法:

public class StructureMapConfig
{
public static IContainer GetContainer()
{
return new Container(container =>
{
container.For<IUserService>().Use<UserService>();
container.For<IStringService>().Use<StringService>();
container.For<IUserRepository>().Use<UserRepository>();
});
}
}

Userservice 的构造函数如下所示:

 public class UserService : IUserService
{
private readonly IUserRepository _userRepository;
private readonly IStringService _stringService;

public UserService(IUserRepository userRepository, IStringService stringService)
{
_userRepository = userRepository;
_stringService = stringService;
}

最后初始化(控制台应用程序中的此实例)看起来像这样:

    private static IUserService _userService;
private static IContainer _container;

static void Main(string[] args)
{
_container = StructureMapConfig.GetContainer();
_userService = _container.GetInstance<IUserService>();
}

所以我的问题。

  1. 我在这里做错了什么吗
  2. 在 UserService 中,我应该传入 IContainer 并使用对象工厂来获取实例,还是应该保持原样。
  3. 从静态方法返回 IContainer 是最好的方法
  4. 如果这是一个 MVC 应用,最佳做法是在 Global.asax 中构建一次,还是 Controller 构造函数每次都调用静态方法。

感谢您的建议。

最佳答案

按顺序回答您的问题:

  1. Am I doing anything seriously wrong here

不,我没有发现这里有什么严重错误。您可以进行一些改进,我将很快讨论这些改进。

  1. In the UserService, should I be passing the IContainer in and using the object factory to get the instance or should I leave as is.

您通过 IContainer 实例注入(inject) UserService 是正确的。如果您的 Controller 只需要 UserService 那么为什么要注入(inject)整个容器。实际上,您只想注入(inject)最少的内容,以减少不必要的耦合和依赖。

  1. Is returning the IContainer from the static method the best approach

在删除 ObjectFactory 后,是的,对于那些不通过 MVC 依赖解析来管理其创建的类来说,通过静态方法返回容器的实例是一种常见方法。

  1. If this was a MVC app, is it best practice to build this once in the Global.asax or should the controller constructor call the static method every time.

Global.asax.cs 中创建容器是最好的方法,因为它在 Application_Start 上完成一次,但是请参阅下面我对每个 http 使用嵌套容器的建议请求。

改进:-

利用 StructureMap 的注册表:

不要像这样直接引用依赖项:

public static IContainer GetContainer()
{
return new Container(container =>
{
container.For<IUserService>().Use<UserService>();
container.For<IStringService>().Use<StringService>();
container.For<IUserRepository>().Use<UserRepository>();
});
}

选择使用 StructureMap 的注册表。通过这种方式,您可以对依赖项进行分组(例如 MVC 特定依赖项或 WebAPI 特定依赖项,如下所示:

public class WebsiteRegistry : Registry
{
public WebsiteRegistry()
{
this.For<IUserService>().Use<UserService>();
this.For<IStringService>().Use<StringService>();
this.For<IUserRepository>().Use<UserRepository>();
}
}

然后像这样加载您的注册表:

container.Configure(c => {
c.IncludeRegistry<WebsiteRegistry>();
c.IncludeRegistry<TaskRegistry>();
});

HTTP 上下文绑定(bind)容器:

将 StructureMap 与 ASP.NET MVC 或 WebApi(或任何基于 HTTP 的应用程序)结合使用时的另一个推荐模式是使用绑定(bind)到每个 HTTP 请求的嵌套容器。这基本上涉及在每个 HTTP 请求上创建一个新的嵌套容器,然后在请求结束时将其处置。这可确保 HTTP 请求结束后立即处理 session 对象、数据库连接或 UoW 上下文等依赖项。

我建议您查看 this article其中更详细地介绍了此事并讨论了如何设置。

这与 StructureMap.MVC5 中使用的技术完全相同。 StructureMap 的创建者 Jeremy Miller 经常推荐的软件包。

自动注册依赖项

您可以利用StructureMap's auto-registration,而不是手动注册StructureMap的每个依赖项。 。您还可以指定自己的扫描约定。

关于c# - 结构图 IContainer 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27575608/

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