我在项目中使用了structuremap和Asp .Net MVC。目前我正在MVC层中为其下面的所有内容(服务,数据等)注册我的依赖项解析。但是,我想知道如何通过仅注册MVC层下面的内容,即服务层来实现这一点。基本上我的控制器注入了服务,这就是我希望我的UI层了解的全部内容。在服务类中,我有注入的存储库,并希望那些在结构图中注册的那些......等等。换句话说,我希望每个图层只能(尽可能地)依赖于它下面的图层。 谢谢!
答案 0 :(得分:2)
我建议在自己的库中使用composition root。
在我正在处理的项目中,我们将StructureMap注册表放在名为xx.yy.IoC的库中,我们从Global.asax调用配置代码。
MVC层只有一个指向IoC库的链接。 IoC库具有与其他层(域,数据等)的依赖关系
作为提示:本文改变了我们对分层的看法。 jeffrey palermo onion architecture
答案 1 :(得分:1)
我不确定我明白你在问什么。
您必须注册将要解析的所有对象。然后在您的控制器中,您只需要将ISomeService传递给构造函数。例如,控制器不知道ISomeService已注入IRepositories。
答案 2 :(得分:1)
一种好的方法是结合结构图注册表使用结构图约定。这将解决您的大部分注册问题。 Structuremap可以扫描您的bin并映射它在bin中所有dll中找到的依赖项。
查看结合了StructureMap注册表类的Scan方法:
Scan(x =>
{
x.AssembliesFromApplicationBaseDirectory(y =>
y.FullName.StartsWith("JustLookAtTheseDlls"));
// Use default conventions
x.WithDefaultConventions().OnAddedPluginTypes(y =>
y.HybridHttpOrThreadLocalScoped());
//Are there any registries? If so, register them
x.LookForRegistries();
}
注册表看起来像这样,你可以在每个项目中放一个注册表来注册每个项目:
public class IocRegistry :
StructureMap.Configuration.DSL.Registry
{
public IocRegistry()
{
For<IDocumentStore>().Singleton()
.Use<RavenStore>();
}
}
您的root应用程序应该具有包含上述扫描语句的注册表。然后像这样初始化结构图:
ObjectFactory.Configure(x => x.AddRegistry(
new MyTopLevelRegistry()));
MyTopLevelRegistry的位置如下:
public class MyTopLevelRegistry: Registry
{
public MyTopLevelRegistry()
{
Scan(x =>
{
x.AssembliesFromApplicationBaseDirectory(
y => y.FullName
.StartsWith("InsertYourNamespacePrefix"));
x.WithDefaultConventions().OnAddedPluginTypes(
y => y.HybridHttpOrThreadLocalScoped());
x.LookForRegistries();
});
}
}
请记住,如果将其设置为“WithDefaultConventions”,它会自动将IMyClass映射到MyClass,因此您甚至不必在注册表中指定这些内容。您只需注册不符合该约定的项目。
希望这有帮助!