简体   繁体   English

使用StructureMap将相同接口的不同实现注入到控制器中的最佳方法是什么?

[英]What's the best way to inject different implementations of the same interface in to a controller using StructureMap?

I am fairly new to StructureMap, but my understanding is that there are two ways of getting an instance from the ObjectFactory : 我对StructureMap相当陌生,但是我的理解是,有两种方法可以从ObjectFactory获取实例:

  1. By type (ie ObjectFactory.GetInstance<IFoo>() ) 按类型(即ObjectFactory.GetInstance<IFoo>()
  2. By type and name (ie ObjectFactory.GetNamedInstance<IFoo>("foo.bar") ) 通过类型和名称(即ObjectFactory.GetNamedInstance<IFoo>("foo.bar")

I have seen a multitude of examples out there demonstrating how to create an MVC Controller Factory that will provide controller instances using StructureMap, and in most cases I have seen, they are using the method from option #1 above. 我已经看到了许多示例,这些示例演示了如何创建一个MVC控制器工厂,该工厂将使用StructureMap提供控制器实例,并且在大多数情况下,我已经看到,他们使用的是上述选项#1中的方法。

Let's say we have some controller that accepts a repository/DAO interface as a constructor arg... 假设我们有一些控制器接受存储库/ DAO接口作为构造函数arg ...

public class FooController : Controller
{
  public FooController (IFooRepository fooRepository)
  {
     // constructor code goes here
  }
}

Using the interface class gives me the ability to "inject" any implementation of that interface in to my controller. 使用接口类使我能够将该接口的任何实现“注入”到我的控制器中。 What if for two different actions, I want to inject different implementations? 如果对于两个不同的操作,我想注入不同的实现怎么办? Perhaps in one case, I need an implementation of my repository that will query a SQL Server database, and in another case, I need an implementation that will get data from an XML file or through a Web Service call. 也许在一种情况下,我需要实现将查询SQL Server数据库的存储库的实现,而在另一种情况下,我需要实现将从XML文件或通过Web Service调用获取数据的实现。

It seems that if you use the ObjectFactory.GetInstance() method, you would be restricted to only providing your controller with a single implementation of your repository interface. 看来,如果您使用ObjectFactory.GetInstance()方法,则将被限制为仅为控制器提供存储库接口的单个​​实现。

However, if you go with named instances, then you will end up having to create the instances based on the name of the controller that the MVC framework provides. 但是,如果使用命名实例,那么最终将不得不根据MVC框架提供的控制器的名称来创建实例。 In most cases, this will typically be the controller name coming from the URL, but it's really up to the route configuration. 在大多数情况下,这通常是来自URL的控制器名称,但这实际上取决于路由配置。 This seems like it could be very confusing, and would only get more confusing as the number of routes increased. 这似乎很令人困惑,并且随着路线数量的增加只会变得更加令人困惑。

Is there any alternative method that would allow for different controller instantiation strategies without using named instances? 是否有其他方法可以使用不同的控制器实例化策略而无需使用命名实例? Would it be a better idea to just create separate controllers, and make sure that all the actions in any given controller will be valid for the same concrete instance of a repository/DAO class? 仅创建单独的控制器,并确保任何给定控制器中的所有操作对于存储库/ DAO类的相同具体实例都有效,这是一个更好的主意吗?

For what it's worth, I ended up going with named instances, where the names of each instance are based on the name of the controller that the MVC framework pulls from the URL. 对于它的价值,我最终使用命名实例,其中每个实例的名称都基于MVC框架从URL中提取的控制器的名称。

For instance, the URL /foo/DoSomething might get an IController instance from the ObjectFactory that is instantiated with a Repository object that uses the SqlClient API for data access. 例如,URL /foo/DoSomething可能会从ObjectFactory获取一个IController实例,该实例是使用Repository对象实例化的,该对象使用SqlClient API进行数据访问。 A URL such as /foo.webservice/DoSomething would then create an instance of the same concrete controller class, but pass that instance's constructor a repository object that uses a web service for data access. 然后,诸如/foo.webservice/DoSomething的URL将创建相同的具体控制器类的实例,但是将该实例的构造函数传递给使用Web服务进行数据访问的存储库对象。

There are several ways to override StructureMap's default auto-wiring behavior for constructor arguments. 有几种方法可以覆盖针对构造函数参数的StructureMap的默认自动装配行为。 In my case, I used the CtorDependency and Is methods, and had mappings that looked something like this... 就我而言,我使用了CtorDependencyIs方法,并且具有看起来像这样的映射...

// create a named instance for the "foo" controller that uses the SqlClient based repository
InstanceOf<IController>()
    .Is.OfConcreteType<FooController>()
    .CtorDependency<IFooRepository>()
    .Is(new FooRepositorySql(Constants.FooConnectionString))
    .WithName("foo");

// create a named instance for the "foo.webservice" controller that uses the Web Service based repository
InstanceOf<IController>()
    .Is.OfConcreteType<FooController>()
    .CtorDependency<IFooRepository>()
    .Is(new FooRepositoryWs(Constants.FooServiceUrl))
    .WithName("foo.webservice");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用StructureMap将不同的依赖项注入到WebApi Controller中 - How to inject different dependencies into WebApi Controller using StructureMap 使用C#StructureMap.Mvc5时,将注入传递给基本控制器的最佳方法是什么? - What is best way to pass injections to base controller when using C# StructureMap.Mvc5? 使用Castle Windsor初始化具有相同类型的多个参数的MVC控制器的最佳方法是什么? - What's the best way to initialize an MVC Controller with multiple parameters of the same type using Castle Windsor? 如何使用StructureMap在ASP.NET MVC中为不同的上下文注入不同的实例? - How to inject different instance(s) for different context in ASP.NET MVC using StructureMap? 将存储库注入ASP.NET控制器的最佳方法是什么 - What is the best way to inject repositories into an ASP.NET controller 如何使用StructureMap将存储库类注入控制器? - How to use StructureMap to inject repository classes to the controller? 我可以使用StructureMap注入一些字符串(例如配置值)到ASP.NET MVC控制器中吗? - Can I inject into an ASP.NET MVC controller, some strings (eg. configuration values) using StructureMap? 如何在StructureMap DI和MVC 5中解析相同类型的多个实现 - How to resolve multiple implementations of the same type in StructureMap DI and MVC 5 按角色将用户定向到不同视图的最佳方法是什么? - What's the best way to direct user to different views by roles? 通过登录的用户角色注入不同的实现 - inject different implementations by logged User Role
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM