2014-07-24 69 views
0

试图在ASP.Net Web API项目中实现依赖注入。Unity依赖注入 - 如何在运行时创建要注入的实例

我希望能够在我的一些服务中注入Account的实例。

Account实例应该与用户Guid一起创建,并且直到运行时才能知道。

所以在我的服务,我有:

 public TransactionService(Account acc) 
     { 
      _account = acc; 
     } 

而在我的应用程序启动时,我可以做到这一点 - 在容器是一个新的UnityContainer

container.RegisterType<Instanet.Engine.Account>(new InjectionConstructor(new Guid("xxxxxx"))); 

这,当然,是不是任何好的,因为它会使用相同Account为每个用户/请求等。

如果我尝试使用类似的东西:

container.RegisterType<Instanet.Engine.Account>(new InjectionConstructor(GetTheUsersID())); 

...其中GetTheUsersID()需要检查Cookie或ASP.Net身份请求,当然在应用程序启动时不可用。 (请简单地说,这个DI东西伤害了我的大脑)我是否实现了这个功能,这样我就可以将实例化的Account注入任何可能需要它的服务中。

回答

0

如果只有一个Account实例可能用于会话,那么我会在所有服务运行之前在引导代码中创建一个Account实例。

然后,您可以在您的帐户实例中填充guid和所有其他数据,并通过container.RegisterInstance方法在Unity中注册Account类的初始化实例。

后来它会解决你所需要的。

它有帮助吗?

+1

谢谢,但并不能真正帮助很大。据我所知,引导程序代码是在应用程序第一次启动时运行的。因此,这个问题 - 我需要的一些信息目前不可用。账户也是遗留的东西,这使得它更加困难。 – Darren

1

您通常不希望为通过容器解决的组件混合使用状态和行为 - DI应该用于可以建模为纯服务的组件。

也就是说,有时在服务组件中包含全局或特定于上下文的状态是有意义的。

在你的情况下,如果你只需要一个或多个服务本地的UserId(换句话说,不是从一个服务传递给另一个服务)。你提到能够得到一个cookie的用户ID,所以也许它会看起来像:

public class CookieService : ICookieService 
{ 
    public int GetCurrentUserId() 
    { 
    //pseudo code 
    return HttpContext.Current.GetCookie["UserId"]; 
    } 
} 

现在,你可以注入ICookieService其中需要用户ID。

更复杂的情况下,可能需要一个抽象工厂:

http://blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/

+0

我完全同意,关于混合行为一点。但我遇到的问题是,服务交互的许多遗留方法需要一个帐户实例 - 所以直到我们的新API建成时,我必须使用遗留的东西。 DI似乎是让账户准备好的更好方式,而不是在服务中新增账户。我确实喜欢你的想法,明天我会给它一个旋风:D谢谢你的好消息。 – Darren