How access ViewContext from helper/service, #injected via ViewImports - asp.net-mvc

I'm writing helper class and inject in in _ViewImports with
#inject HtmlHelperInject.TestHelper TestHelper
And register in Startup.ConfigureServices with
services.AddTransient<TestHelper>();
How can I obtain ViewContext in this helper class? I tried injecting via controler - not working, via [ViewContext] attribute on property - not working.

As of right now (beta8) the way to do this is to implement... wait for it... ICanHasViewContext. This interface adds the following contract:
void Contextualize(ViewContext viewContext);
When injecting your custom utility MVC calls Contextualize and passes in the current ViewContext. Note: this mechanism will most likely change in future releases. If not, the name certainly will :)
Hope this helps!

Related

Blazor client side [inject] properties always return null

In razor pages I'm using #inject Blazored.LocalStorage.ISyncLocalStorageService localStorage and it's working fine. But from non-razor connected classes (services and helpers) using
[Inject]
protected Blazored.LocalStorage.ISyncLocalStorageService localStorage { get; set; }
Always returns null. Is there something additional that is needed to get DI to work in non-Razor files? Or do I have to push all of the DI through Constructors all the way down from the UI layer?
The following is based only on my own experience, so I might be proved wrong...
Only constructor injection works in non-razor objects. Thus you cannot define a property annotated with the Inject attribute and expect it to be populated with an instance of a given object. Use constructor injection instead.
With Razor objects, however, you can use the #inject directive to inject services into Razor components, but you can also use the Inject attribute with properties in razor component class definition (.razor.cs ) and in #code blocks ( .razor ).
Hope this helps...

Play Framework: Dependency Injection inside Action

Short version: how to inject an object inside Action in Play Framework?
Long version: In my project I have custom annotation action #AuthenticationRequired which loads User object from the database and puts it into context.args. It uses DAO class that implements UserDAO. Now I want to use DAO class injected into Action by Google Guice. I can use Guice and inject instances in controllers and tests, but I have difficulties injecting DAO class inside Action.
Injector is a field on GlobalSettings instance.
I tried to override GlobalSettings#onRequest() and put UserDAO instance to context.args and then retrieve it from inside AuthenticationRequired action, but it turns out that Action returned by GlobalSettings#onRequest() being called last in the chain of action used with #With and/or custom annotations, so, it is to late.
I also tried to inject DAO instance by annotating action constructor, but but it uses no-args constructor to create an instance of action.
Any ideas how can I achieve this?
For play 2.5 you can simply add #Inject on top of the constructor of Action class and inject whatever needed. Here is a snippet from my working project (I'm using Guice as DI):
public class ChannelPermissionAction extends Action<ChannelPermission> {
private final AuthorizationService authorizationService;
private final AsyncHelper asyncHelper;
#Inject
public ChannelPermissionAction(AuthorizationService authorizationService, AsyncHelper asyncHelper) {
this.authorizationService = authorizationService;
this.asyncHelper = asyncHelper;
}
...
}
You can achieve this just the same as with controllers - describe your action as (a bean in my case - i'm using spring IoC) a dependency and get it called by
public <A> A getControllerInstance(Class<A> clazz)
of Application Global object. That's all you need - you'r dependencies would be injected.
BTW. Actions need to be created with each instance so in my case I should use "prototype" scope.
Mind it while using Guice - it should have similar functionality.

ActionFilterAttribute ninject injection - DbContext has been disposed

I have my project which uses the usual Repository pattern with Services and Unit of Work (all with Ninject injecting the dependencies from a NinjectModule), but I'm trying to access a service from an ActionFilterAttribute to inject some information (from DB) in the layout of the pages I show so I don't need to mess with all the actions on each controller.
The problem comes when I save to DB on one screen and move to the next and then come back to the previous (with a standard #Url.Action): The ActionFilterAttribute for the Index action is triggered but the call to the service and corresponding repository (within the attribute) throw an exception because the DbContext has been disposed.
Is there any problem with accessing a service and, consequently, the DbContext from an ActionFilterAttribute while injecting the service via Property Injection? I want to make a note that I use property injection for the service in the attribute because the constructor receives 2 parameters that are arbitrary depending on the signature of the Action methods, so my only option was to inject via property.
Let me know if you need some code and I'll update the question.
I found the solution to my problem in the following question:
Injecting dependencies into ASP.NET MVC 3 action filters. What's wrong with this approach?
Combining Mark Seeman's answer with striplingwarrior's comment was the solution to it.
Basically I splitted my ActionFilterAttribute into an Attribute that merely decorated my Actions and keeps the parameters I need for later, and also into an ActionFilter that checked the Action's custom attributes and if my attribute exists, then it injects the data I wanted from the DB into the ViewBag. Everything is later binded with the BindFilter extension from Ninject so it applies only to the methods it needs.

Castle windsor property injection

Im a windsor noob and im having some problems getting dependency injection to work. im using a asp.net web application.
I have done the following
public interface IHandler{
...
}
public class Handler : IHandler{
...
}
then i try to register the code in global.asax application_start
container.Register(Component
.For(typeof(IHandler))
.ImplementedBy(typeof(Handler))
.Named("handler"));
When i want to use the Handler i create a property
public IHandler handler{get;set;}
but when i try to use it, it is null? why? am i missing someting?
Best regards
UPDATE
The only thing i doto register/resolve is the following:
container.Register(Component
.For(typeof(IHandler))
.ImplementedBy(typeof(Handler))
.Named("handler"));
and:
container.Resolve<IHandler>();
Do i need to do something else, Does it work to run this att application start?
UPDATE 2
Can the problem ocour because im trying to dependency inject on an ascx controll?
Make sure the component that has the IHandler property is also registered (and resolved) in Windsor.
You said this is for an ASP.NET application. The default lifestyle of Windsor components is singleton. Are you sure you want this component shared like that? You may want a transient or per-web-request lifestyle for this component.
Try removing the name from the registration, like this:
container.Register(Component
.For(typeof(IHandler))
.ImplementedBy(typeof(Handler)));
Alternatively, if you must name the component, you can use ServiceOverrides for the consuming class:
container.Register(Component
.For<SomeConsuer>()
.ServiceOverrides(new { handler = "handler" }));
If you are going to be registering several interfaces/services, then I recommend registering by convention (this is recommended in the docs). Consider this:
container.Register(
AllTypes.FromAssemblyNamed("Assembly")
.Where(Component.IsInNamespace("Assembly.Namespace"))
.WithService.DefaultInterface()
.Configure(c => c.LifeStyle.Transient));
This method performs matching based on type name and interface's name. More info Registering Components By Convention

CastleWindsor filling the class fields too

I am a beginner using castle windsor; and kinda introduced to it with Apress Pro Mvc book. In the project that I am working at; I use castlewindsor controller factory instead of mvc controller factory; so i can have parametrized constructors and i can inject the dependencies.
Is there a way to tell the windsorcontroller factory to inject the values to the properties of the controller class without going through constructor?
The reason I want to do this is because I have Logging dependency; Emailler Dependency; Database Dependency; Theme Engine dEpendency; and I dont want to use this many parameters parameter in the constructor.
By default, when Windsor resolves a service implementation, it will populate all properties with public setters that it can satisfy.
However, take notice that sometime it does make sense to put the dependency resolving in the constructor, for that fact that it guarantees that any instance will always be in a valid state. Consider Unit Testing scenario, where the person writing the test will go crazy about the need to know which dependencies should be supplied. When all dependencies goes into the c'tor, the tester will have no choice but to supply the tested instance with all the required dependencies (as stubs or mocks).
Anyway, as for your question, Windsor support C'tor and property injection by default
Castle Windsor will automatically fill any properties with public setters that it knows how to fill.
This means if you have a class
public MyClass {
public SomeDependency {get; set;}
}
As long as the container is configured to know how to resolve SomeDependency it will attempt to resolve and inject it.
Sometimes I've found this default behavior to be hassle. This facility will give you finer grained control over the process.

Resources