StructureMap - 注入特定实例。如何?

时间:2012-11-09 17:30:59

标签: c# .net dependency-injection structuremap

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

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并选择适当的状态。这是一种合理的方法吗?如果收藏很大会怎么样?

1 个答案:

答案 0 :(得分:2)

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

public interface ICurrentUserService
{
    State State { get; }
}
  

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

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

  

如果收藏品很大会怎么样?

这听起来像对我来说过早优化。如果它足够快,它足够快。但是当集合随着时间的推移而增长并且速度变慢时呢?好吧,当您在消费者中将其实现为LINQ语句时,这可能很难解决,因为现在您将不得不更改所有使用者。如果你在ICurrentUserService抽象的实现(或者你想要调用的任何东西)中编写这个LINQ语句,那只是一个简单的重写问题。只需将LINQ查询更改为使用Dictionary<string, State>即可。