I am trying to inject a dependency into a custom AuthorizeAttribute as follows:
public class UserCanAccessArea : AuthorizeAttribute
{
readonly IPermissionService permissionService;
public UserCanAccessArea() :
this(DependencyResolver.Current.GetService<IPermissionService>()) { }
public UserCanAccessArea(IPermissionService permissionService)
{
this.permissionService = permissionService;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
string AreaID =
httpContext.Request.RequestContext.RouteData.Values["AreaID"] as string;
bool isAuthorized = false;
if (base.AuthorizeCore(httpContext))
isAuthorized = permissionService.UserCanAccessArea(AreaID, httpContext.User);
return isAuthorized;
}
}
This works but seems to be resolving as a singleton meaning I get the problems described in my pervious question
What I'd like to do is use property injection but as my Attribute itself is not resolved by Unity I'm unable to find a way to configure the container to intercept and resolve a property. I have tried the following:
public class UserCanAccessArea : AuthorizeAttribute
{
public IPermissionService permissionService { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
string AreaID =
httpContext.Request.RequestContext.RouteData.Values["AreaID"] as string;
bool isAuthorized = false;
if (base.AuthorizeCore(httpContext))
isAuthorized = permissionService.UserCanAccessArea(AreaID, httpContext.User);
return isAuthorized;
}
}
Container:
container.RegisterType<UserCanAccessArea>(new InjectionProperty("permissionService"));
But the property is always null at runtime.
Has anyone achieved this and if so do you have an example?
You should prevent doing dependency injection into attributes completely. The reason for this is explained in this article: Dependency Injection in Attributes: don’t do it!. In summary the article explains that:
Constructor injection is not possible, because creation of an Attribute instance cannot be intercepted; the CLR is in control.
The use of property injection is fragile, since it results in Temporal Coupling, which should be prevented.
Dependency injection into attributes makes it impossible to verify
the correctness of the container's configuration.
Frameworks like MVC and Web API cache attributes, making it very easy to accidentally create captive dependencies causing bugs.
You have two choices here:
Make the attributes passive, by splitting the data (the attribute) from its behavior (the service) as explained in the referenced article and this related article from Mark Seemann.
Turn your attributes into humble objects as explained in this answer. This means you:
extract all logic from the attribute into a custom service that contains all dependencies.
Register that service in your container.
let the attribute's method (AuthorizeCore in your case) do nothing more than resolving the service from the service locator / DependencyResolver and call the service's method. Important to note here is that you cannot do constructor injection, property injection and the service cannot be stored in the attributes private state (as you already noticed).
Which option to use:
Use option 1 if you are very keen into keeping your design clean, or you have more than a few attributes that you need to apply this way, or you want to apply attributes are defined in an assembly that doesn't depend on System.Web.Mvc.
Use option 2 otherwise.
In ASP.NET Core, this is now possible by either creating a custom attribute, implementing IFilterFactory, or by using TypeFilterAttribute, as well as ServiceFilterAttribute.
Both implement IFilterFactory and do what you'd normally do in your custom attribute implementing IFilterFactory, the only difference is that they support ordering (which you can add if you wish in your custom attribute).
But more specifically - ServiceFilterAttribute gets the instance of your filter from the actual service collection, which allows you to define a specific lifetime to it, whereas TypeFilterAttribute does not use the service collection to create your object, it uses Microsoft.Extensions.DependencyInjection.ObjectFactory which is the result of CreateFactory method. (Basically it creates your object with a lot of expression trees.) TypeFilterAttribute also allows you to pass arguments for non-service constructor parameters. Both use the service collection for any DI.
For your existing codebase you can quite simply do any of the following to achieve Dependency injection in the constructor of an attribute:
[TypeFilter(typeof(MyExistingFilterWithConstructorDI))]
[TypeFilter(typeof(MyExistingFilterWithConstructorDIAndParams), Arguments = new object[] { "first non-service param", "second non-service param" })]
[ServiceFilter(typeof(MyExistingFilterWithConstructorDI)) (you will need to register your filter into the service collection with an appropriate lifetime)
Now, as far as performance goes, if you end up using TypeFilterAttribute, the type for your filter will be created as mentioned above, with expression trees, whereas if you simply create your own IFilterFactory, you control that part, i.e you simply instantiate your object, and for any dependency injection needs - you use the provided IServiceProvider as part of the CreateInstance method for the interface.
The IsReusable property, as part of the IFilterFactory interface is there for you to show if you prefer the framework to use your object outside of the request scope. This, in no way guarantees that you'll ever be stuck with a single object for your filter.
I implemented it like this:
public class ClaimsHandlerAttribute : AuthorizeAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
var jwtAuthManager =
context.HttpContext.RequestServices.GetService(typeof(IJwtAuthManager))
as JwtAuthManager;
return;
}
}
Related
I'm using a custom JsonConverter and JsonSerializerSettings.TypeNameHandling = TypeNameHandling.Objects to create the required instances during deserialization. The instances are created by resolving the types from an Autofac IOC container. Everything works fine, except...
I have several "core objects" that request a unique Id in the constructor from a service (which is correctly injected into the constructor). When deserializing this should not happen because it is fairly expensive and the Ids will be populated from the Json file anyway once the instance has been created.
Currently, when resolving from within the custom JsonConverter I'm using _scope.Resolve<T>(new TypedParameter(typeof(IIdService), null)); to then - in the called constructor - check for null and act accordingly.
Some people apparently consider multiple constructors worse than a code-smell when using an IOC (which makes me wonder why Autofac offers several features regarding the topic), but in the context of deserialization I think it can make perfect sense.
As far as I can tell Autofac has mechanisms to decide which constructor to use during registration, but not when resolving. My preferred solution would be to add a custom attribute to a constructor (e.g. [CtorForDeserializing]) and use that for deciding. Is that possible?
There are a couple of extension points Autofac has for reflection-based activations but doesn't have well documented yet that may help you out: IConstructorFinder and IConstructorSelector.
IConstructorFinder is used to locate all the available constructors on a type. The core example is the DefaultConstructorFinder which locates only public constructors. If you wanted to, say, hide constructors with particular attributes or start finding internal/private constructors, you could create a custom finder. This really only happens once so you don't get to make runtime choices here.
IConstructorSelector is used to choose, at resolve time, which constructor should be used to instantiate the object. There are a couple of these in core Autofac, but the primary example is the MostParametersConstructorSelector which selects the constructor that has the most available matching parameters at the time. Constructors get found by the IConstructorFinder and then that set of constructors is what is presented to the IConstructorSelector to choose from. This is where you could make more runtime choices since it happens every time the object is resolved.
There are extension methods to help you add your finder/selector to a registration:
builder.RegisterType<MyType>()
.FindConstructorsWith(new MyConstructorFinder())
.UsingConstructor(new MyConstructorSelector());
You don't have to customize both things, you can just do one or the other if you want. I'm just showing you the extensions.
Actually Autofac is able to decide which constructor to use both ways - during registration or resolution. For resolution part here is the quote from documentation: "Autofac automatically uses the constructor for your class with the most parameters that are able to be obtained from the container" (see here).
Consider following example.
public interface ISomeService
{
Guid Id { get; }
}
public class SomeService : ISomeService
{
public Guid Id { get; }
public SomeService()
{
Id = Guid.NewGuid();
}
public SomeService(Guid id)
{
Id = id;
}
}
// Startup.cs:
builder.RegisterType<SomeService>().As<ISomeService>().InstancePerLifetimeScope();
// TestController.cs:
[Route("api/[controller]")]
public class TestController : Controller
{
private readonly IComponentContext _context;
public TestController(IComponentContext context)
{
_context = context;
}
[HttpGet]
public IActionResult Get()
{
var service = _context.Resolve<ISomeService>();
return Ok(service.Id);
}
[HttpGet("{id}")]
public IActionResult Get(Guid id)
{
var service = _context.Resolve<ISomeService>(new NamedParameter("id", id));
return Ok(service.Id);
}
}
// GET http://localhost:5000/api/test/e0198f72-6337-4880-b608-68935122cdea
// each and every response will be the same: e0198f72-6337-4880-b608-68935122cdea
// GET http://localhost:5000/api/test
// this way it responds with some random guid each time endpoint is called
Travis Illig sent me in the right direction - thanks!
I ended up implementing a solution around the following details:
Implement custom attributes, e.g.: public class DeserializeCtorAttribute : Attribute { }, which will be used by the (also to be implemented) IConstructorFinder.
Implement an empty generic interface, e.g.: IDeserializable<T>, which will be used for resolving the services/components.
Let relevant component classes implement the interface (MyClass : IDeserializable<MyClass>) and add an extra registration for the component:
_builder.RegisterType<MyClass>().As<IDeserializable<MyClass>>()
.FindConstructorsWith(MyConstructorFinder);
Use the implemented DeserializeCtorAttribute in the desired constructor of MyClass.
Let the JsonConverter create the required instance by calling (MyClass) scope.Resolve(IDeserializable<MyClass>); casting is required, but safe. Due to the registration the instance will be created using the desired constructor.
I did my best with the title. What I am trying to accomplish is tiered modularity with dependency injection. Whether or not this design pattern is good is a question for another forum.
Because I am using dependency injection, I have interface/implementation pairs. This is the top-level inteface:
public interface IConfiguration<T> where T : ConfigData
{
T GetConfig();
}
Where ConfigData is a simple class that exposes get/set properties like LogLevel and Environment.
There is a base implementation of the interface:
public abstract class ConfigurationBase<T> : IConfiguration
{
protected ConfigData Config { get; set; }
public T GetConfig()
{
return Config as T;
}
}
Now for the dependency injection part of this! I have several interface/implementation pairs that hierarchically inherit from one another. Furthermore, their protected Config property also exposes more properties in each subsequent child class. Here are my interface/implementation signatures:
public interface IGeneralConfiguration : IConfiguration<GeneralConfigData>
public class GeneralConfiguration : ConfigurationBase<GeneralConfigData>, IGeneralConfiguration
public interface ILoginConfiguration : IConfiguration<LoginConfigData>, IGeneralConfiguration
public class LoginConfiguration : ConfigurationBase<LoginConfigData>, ILoginConfiguration
public interface IAppConfiguration : IConfiguration<AppConfigData>, ILoginConfiguration
public class AppConfiguration : ConfigurationBase<AppConfigData>, IAppConfiguration
Note that the inheritance scheme for the config data element is ConfigData → GeneralConfigData → LoginConfigData → AppConfigData. The config data element just exposes more properties specific to login/the application etc. (like Username or StartUri) in each child.
Now, I can use this configuration concept across all my modules. As far as dependency injection goes, resolving IGeneralConfiguration, ILoginConfiguration or IAppConfiguration will yield the exact same instance. However, now general modules only need to resolve IGeneralConfiguration, modules specific to login will only need to resolve ILoginConfiguration, and app-specific modules can resolve IAppConfiugration, all so that they can access parts of their config data specific to the concern they are trying to handle. This modularity allows me to create smaller side-apps that reuse modules from the main application without having to do a lot of custom coding (for example, I can reuse the login module without the need for referencing app-specific modules) as long as I slightly alter my dependency registration.
If you are still with me up to this point, the only problem with this model is that in all of my sub classes (that inherit from ConfigurationBase<T>), they all need the ConfigData() implementation from the interface above them. This means that class LoginConfiguration needs a method definition for public GeneralConfigData GetConfig(), and class AppConfiguration needs a method defintion for both public GeneralConfigData GetConfig() as well as LoginConfigData GetConfig().
So fine. I do that. Now, in my application-specific modules, I get a compiler error. Up in my class field definitions, I have private IAppConfiguration _appConfiguration;. Later in a method, I make a reference to it:
var element = _appConfiguration.GetConfig().AppSpecificConfigElement;
The compiler is confused, saying
the call is ambiguous between the following or properties 'IConfiguration.GetConfig()' and 'IConfiguration.GetConfig()'
Why doesn't the compiler see that the type is IAppConfiguration and define the call to GetConfig() to the AppConfiguration's GetConfig() (where T is defined as AppConfigData)?
Is there an obvious way to disambiguate the call to GetConfig() using my scheme?
If I understand correctly then what you just did is that you have two methods that have same signature except for the return value which cannot be resolved automatically. Compiler doesn't (and cannot) traverse all subclasses derived from ConfigData to determine that AppSpecificConfigElement belongs to AppConfiguration and pick overload based on that - even if it did you can have multiple classes that have AppSpecificConfigElement property so it won't be much wiser. You need to help compiler understand what you need, either by typing _appConfiguration to proper type or using typed descendant of ConfigData instead of var in your statement first and then get property.
In both cases I think you seriously over-engineered and I would suggest to step back and reconsider your approach. As #zaitsman said these objects should be POCOs and have different loader (DB, filesystem, ...) implementing simple Load/Save interface that can be then passed to DI based on context.
So, I have a web project that utilizes Unity to inject UserRepository for interfaces IUserRepository. I have a class library which contains a custom ActionFilterAttribute. This custom attribute class is used on many actions already. I want to add some code to it to check for a value in the database based on a user. To do this, I need access to the UserRepository. I could do it the old fashioned way with using statements and directly access UserRepository, but I would like to utilize the DI and resolve IUserRepository. How can I get access to what the web is resolving IUserRepository to, inside the custom attribute class since ActionFilterAttribute needs an empty constructor?
Attributes are metadata objects. They shouldn't be involved in database access. Use a separate service to read the attribute values and as a result access the database.
So, although I decided to not do the user check inside the custom attribute, the solution to allow for the injection inside the custom attribute can be used elsewhere. I had a property in the attribute:
public IUserRepository UserRepository { get; set; }
In the web's Global.asax.cs, I injected it via a property injection:
container.RegisterType<NameOfCustomAttribute>(new InjectionProperty("UserRepository",
new UserRepository(ConfigurationManager.ConnectionStrings["DBName"].ConnectionString)));
This is an old question, but I found you can access your dependency resolution in an ActionFilterAttribute by using the actionContext parameter like so:
MyFooService myFooService = actionContext.Request.GetDependencyScope().GetService(typeof(MyFooService)) as MyFooService;
What is best way to get injections in base controller when using C# StructureMap.Mvc?
I can think of these 2 ways and don't know which is better.
From controller arguments to base controller arguments
(Nice approach but becomes a mess when there are many controllers with many properties to be injected)
Don't use child controller and initiate all injections using ObjectFactory.CreateInstance() in base controller constructor
(Very less code and manageable but not considered as good practice when Controller Injection is available)
thanks in advance.
I think bother approaches are fine and you can use the mix of both. Of course depending in the situation.
A. I believe if your child Controller require a dependency to be injected, then use the Constructor injection. This way you Controller's constructor API is explicit and it should state what has been injected into the Controller. Easy to read, and easy for discoverability. If you try to hide your DI types in a factory you lose this nice API/discoverability. Use property injection when the dependencies are optional if you think so. You don't really have pass these to the base Controller unless all your Child Controllers use them.
If you think you overloading the types in your Controller, try to aggreagate those interfaces to a single types.
B. It is not advisable to directly use the Structure map ObjectFactory in your Controller. Your Controllers should be agnostics of any infrastructure DI work. You can make use a generic factory (in infrastructure) to create types which uses the ObjectFactory within. If your DI types are required by the base Controller you may use this factory to resolve those types.
The ideas, inject types only when/where they need. Avoid injecting types to Controllers when they don't use/need.
Another option you available to you is setter injection via StructureMap's ObjectFactory.BuildUp() method.
It's worth mentioning that in StructureMap 3.1 the ObjectFactory has been deprecated in favour of injecting an instance of IContainer.
The examples would look like this:
StructureMap 3.0 and below:
public class BaseController {
protected IMyExampleServer MyExampleService { get; set; };
public BaseController() {
ObjectFactory.BuildUp(this);
}
....
}
StructureMap 3.1+:
public class BaseController {
protected IMyExampleServer MyExampleService { get; set; };
public BaseController(IContainer container) {
container.ObjectFactory.BuildUp(this);
}
....
}
Using StructureMap 3.1 would mean you'd only need to inject an instance of IContainer into your derived controller rather than each individual dependency that your base class requires.
Let's suppose I have two different concrete classes that both implement the same interface:
public interface IDataSource{
Connection CreateConnection();
}
public class DataSourceA: IDataSource
{
....
}
public class DataSourceB: IDataSource
{
....
}
Now I want to register both of these with my unity container:
var container = new UnityContainer();
container.RegisterType<IDataSource, DataSourceA>("A");
container.RegisterType<IDataSource, DataSourceB>("B");
I know that I can specify the mapping name when I resolve a dependency :
var myDataSource = conatiner.Resolve<IDataSource>("A");
However, in my case, I won't be resolving the dependency myself. I am creating many different controllers and I will be using UnityDependencyResolver (from ASP.Net MCVC) to create all the controllers. Some of my controllers required DataSource A, some require DataSource B, and some require both. What I'd like to do is specify which one to use as an attribute on the constructor parameter, like this:
public class ReportController{
public ReportController([InjectionQualifier("A")] IDataSource dataSource)
{
...
}
}
Is something like that possible? I come from the spring world in java and I would use an #Qualifier annotation in this case using that stack.
The attribute you are looking for is
[Dependency("A")]
With Unity how do I inject a named dependency into a constructor?
I personally don't like using the Dependency Attribute because you're directly depending on the Unity library. You might as well pass in the IUnityContainer in your constructor.
Usually when you need to use named dependencies, it's because you are trying to implement some kind of strategy pattern.
What I do is that I isolate Unity in a class called StrategyResolver and inject the StrategyResolver as dependency. Since the StrategyResolver belongs to me then my "services" classes no longer have any hard dependencies on any Unity library objects except inside the StrategyResolver but that's acceptable since I will never have to modify the StrategyResolver ever again when adding new strategies in the future.
Take a look, I've detailed my approach in this answer with code examples : https://stackoverflow.com/a/37882179/483638