在运行时注入值

时间:2015-05-21 11:26:00

标签: c# asp.net-web-api unity-container

我的存储库类需要从Thread.CurrentPrincipal获取运行时值(即授权声明)以及常规单例类。

给出

public class MyRepository : IMyRepository
{
    private readonly DependencyClass _dependency;
    private readonly string claim;

    protected MyRepository(DependencyClass _dependency, string claim)
    {
        //...

注册存储库时,如何注入声明? e.g。

unity.RegisterType<IMyRepository, MyRepository>(new HierarchicalLifetimeManager());
unity.RegisterType<DependencyClass>(new ContainerControlledLifetimeManager());

InjectionConstructor似乎与构造函数参数匹配,因此导致运行时错误。我仍然更喜欢构造函数注入,我只是不确定如何做到这一点。

1 个答案:

答案 0 :(得分:4)

  

我有需要运行时值的存储库类

你的DI容器应该构建包含注射剂/组分的对象图;包含应用程序逻辑的类。运行时数据不应该注入组件的构造函数中,因为这会使构造,构建和验证对象图变得复杂。

相反,应使用方法调用将运行时数据传递给对象图。这种上下文运行时数据的一般解决方案是拥有一个抽象,为其消费者提供这种上下文数据。

例如,在您的情况下,transaction-manager-ref抽象可以解决问题:

<jpa:repositories base-package="com.foo.webapp.test.repository"
    entity-manager-factory-ref="entityManagerFactory1" 
    transaction-manager-ref="transactionManager1" />

<jpa:repositories base-package="com.foo.webapp.repository"
    entity-manager-factory-ref="entityManagerFactory2" 
    transaction-manager-ref="transactionManager2" />

使用这种抽象,创建一个从IClaimsContext读取声明的实现很简单,如您所见:

public interface IClaimsContext {
    string CurrentClaim { get; }
}

由于此实现不包含任何状态,因此可以将其注册为singleton而不会出现任何问题:

Thread.CurrentPrincipal

现在,public sealed class ThreadClaimsContext : IClaimsContext { public string CurrentClaim { get { return Thread.CurrentPrincipal... /* get claims here */; } } } 只能依靠unity.RegisterInstance<IClaimsContext>(new ThreadClaimsContext()); 代替MyRepository