Reputation: 5162
I have repository classes that require runtime values taken from Thread.CurrentPrincipal
(i.e. authorization claims) in combination with regular singleton classes.
Given
public class MyRepository : IMyRepository
{
private readonly DependencyClass _dependency;
private readonly string claim;
protected MyRepository(DependencyClass _dependency, string claim)
{
//...
When registering the repository, how can the claim be injected? e.g.
unity.RegisterType<IMyRepository, MyRepository>(new HierarchicalLifetimeManager());
unity.RegisterType<DependencyClass>(new ContainerControlledLifetimeManager());
InjectionConstructor
seems to match the constructor parameters and therefore causes a runtime error. Still I'd prefer constructor injection, I'm just not sure how do that.
Upvotes: 3
Views: 474
Reputation: 172646
I have repository classes that require runtime values
Your DI container should build up object graph that contain injectables/components; the classes that contain your application's logic. Runtime data should not be injected into a component's constructor, because that will complicate constructing, building and verifying the object graphs.
Instead, runtime data should be passed through the object graph using method calls. A general solution for this kind of contextual runtime data is to have an abstraction that provides this contextual data to its consumers.
In your case for instance, an IClaimsContext
abstraction does the trick:
public interface IClaimsContext {
string CurrentClaim { get; }
}
Using this abstraction, it is trivial to create an implementation that reads the claims from the Thread.CurrentPrincipal
as you can see here:
public sealed class ThreadClaimsContext : IClaimsContext {
public string CurrentClaim {
get { return Thread.CurrentPrincipal... /* get claims here */; }
}
}
Since this implementation contains no state, it can be registered as singleton without any problem:
unity.RegisterInstance<IClaimsContext>(new ThreadClaimsContext());
Now your MyRepository
can simply depend on IClaimsContext
instead of a string claims
.
Upvotes: 4