【问题标题】:StructureMap - injecting specific instance. How to?StructureMap - 注入特定实例。如何?
【发布时间】:2012-11-09 17:30:59
【问题描述】:

假设我定义了这个简单的类:

public class State
{
    public int Id { get; set; }
    public string Name { get; set; }
}

然后我将定义、创建和注册 50 个命名实例。用户登录,我知道(比如从他的配置设置)他来自哪个州。在我的控制器中很容易说

var userState= ObjectFactory.GetNamedInstance<State>("Idaho");

但我更愿意将它传递给构造函数,如下所示:

public class HomeController : ControllerBase
{
    private State _state;

    public HomeController(State state)
    {
        _state = state;
    }
}

但是,要使其正常工作,必须传递一个特定的实例。有没有办法指定这个?

我刚刚想到的另一件事。我可以将其定义为一组状态,而不是定义 50 个单独的状态,如下所示:

public class StateCollection
{
    public List<State> States { get; set; }
}

然后在构造函数中传递 StateCollection。然后客户端可以使用 LINQ 并选择适当的状态。这是一个合理的方法吗?如果集合很大怎么办?

【问题讨论】:

    标签: c# .net dependency-injection structuremap


    【解决方案1】:

    您想要做的就是所谓的基于上下文的注入。尽管有可能这样做,但基于上下文的注入通常表明应用程序设计中存在错误。在您的情况下,您似乎缺少一个简单的 ICurrentUserService 抽象,它提供有关系统中当前用户的信息:

    public interface ICurrentUserService
    {
        State State { get; }
    }
    

    然后客户端可以使用 LINQ 并选择适当的状态。 这是一个合理的方法吗?

    不,可能不是,因为这让客户端负责为用户找到正确的状态,而您已经知道这一点。再次,使用正确的抽象。这使得客户端代码更容易。

    如果集合很大怎么办?

    对我来说,这听起来像是过早的优化。如果它足够快,它就足够快了。但是当集合随着时间的推移而增长并且变慢时怎么办?好吧,当您在消费者中将其实现为 LINQ 语句时,这可能很难解决,因为现在您必须更改所有消费者。如果您在ICurrentUserService 抽象(或任何您想称呼它的名称)的实现中编写此 LINQ 语句,则只需简单的重写即可。只需将 LINQ 查询更改为使用 Dictionary&lt;string, State&gt; 即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多