【发布时间】:2016-03-09 16:58:03
【问题描述】:
是否可以使用 StructureMap 扫描程序集以了解未实现接口的具体类?我对 StructureMap 很陌生,所以不确定这是否应该是显而易见的事情。
对于上下文,以下是我正在使用的课程的亮点。 UserController 依赖于 UserManager 的实例,而 UserManager 依赖于 IUserRepository 的实例。
public interface IUserRepository { }
public class UserRepository { }
public class UserManager
{
public UserManager(IUserRepository repository) { }
}
public class UserController
{
public UserController(UserManager manager) { }
}
这是我在 Startup.ConfigureServices 方法中用于扫描 DI 的代码:
// Setup dependencies using StructureMap
var container = new Container(x =>
{
x.Scan(s =>
{
s.AssemblyContainingType<UserRepository>();
s.WithDefaultConventions();
});
});
container.Populate(services);
问题是我收到以下错误:
尝试解析“UserManager”类型的服务时无法解析 激活“用户控制器”。
如果我将以下行添加到Startup.ConfigureServices,那么它可以工作,但我正在寻找一种不需要我为每个经理都设置一行的解决方案。我一直认为 StructureMap 程序集扫描可以解决这个问题,但我也愿意接受其他解决方案。
services.AddTransient<UserManager>();
【问题讨论】:
-
我会重新考虑您的架构。您可以使用 StructureMap 作为您的 DI 容器,但如果您这样做,它应该处理您的所有依赖项,并且您可以消除对内置容器的依赖。至于扫描依赖项,如果您只拥有一个不实现接口或抽象类的具体对象,那么您最好还是硬编码对象引用,因为当您的容器没有机会进行替换时已经引用了具体的类。扫描程序集类似于不受欢迎的服务定位器模式。
-
@Phasiq 你的评论让我退后一步思考。因为我总是知道在 UserController 中为 UserManager 使用什么具体类,所以我不需要使用 DI 来创建该依赖项,而是可以根据需要在控制器中创建它,这是您的建议吗?
-
嗯,有点。如果您对具体类有硬依赖,那么使用 DI 容器对其进行实例化确实没有必要,而且几乎没有什么好处。但是,我真的会考虑未来的灵活性和测试。让你的类实现一个接口/抽象类肯定有助于防止未来的变化破坏你现有的架构。有严格依赖的时间和地点,但我发现它在控制器类中很少见。如果你正在编写单元测试,我肯定会实现一个接口或抽象类。
-
@Phasiq 知道了,如果我在 UserManager 类中构造具体的依赖关系,那么我肯定会得到一个服务定位器模式,因为我必须将容器传递给控制器来解决其他依赖项。不过,我对测试我的控制器不感兴趣,他们只会调用经理,并且不应该有任何需要在其中测试的逻辑。这给我留下了可以在其他项目中使用的库,并且重复的代码最少。
-
我是否最终得到了这里不鼓励使用的洋葱架构:structuremap.github.io/best-practices?
标签: asp.net-core structuremap structuremap4