soundaranbu/Razor.Templating.Core

Inject services into a view

anddrzejb opened this issue · 10 comments

I was trying to load a service from DI into a view using @inject but it does not work. I get an error No service for type 'Microsoft.Extensions.Configuration.IConfiguration' has been registered.'.
What I was trying to get was Microsoft.Extensions.Configuration.IConfiguration service, so I can get some data directly for one of the partial views (namely location of a logo for my report heading partial view).
Is there a way to get a service from DI?

Hi @anddrzejb, definitely I'll look into this use case.
In the mean time, if you wish, you can use the conventional approach which is passing all the required data to the view using the View Model as shown here

Thanks for your response. Unfortunately I did not like your solution. I do not think model should be polluted with data not related to the model itself. So what I did, I created my own RazorTemplateEngine, based mainly on what you did, except it is not a static
class and it is injected as a scoped service. I realise this is probably less universal, but my needs are limited only to ASP.NET Core. This way I can request the RazorTemplateEngine service whenever I need it and I can inject any service I registered in my DI to any view.

Glad that you found a workaround. I'm already trying to add this feature to the library specific to ASP.NET Core. You can expect it in the next release.
Between, where are your view files located? Is it in the same project(ASP.NET Core) or in separate Razor Class Library(RCL)

I was just migrating to 5.0 and I noticed your change screwed me, because you made RazorViewToStringRender internal.

Regarding my project (for reporting) - for the time being I have 2 RCL libraries - 1 that provides base classes and basic layouts and partial views, and another that contains my report templates. The service installer is in the 1 project with base classes. Then I use the reports in blazor and in webapi (some reports need to return as pdf so they are created in webapi and pdf file is returned).

I'm sorry to hear that making RazorViewToStringRender as internal made your life difficult. The reason is to expose only the necessary apis to the public as it was created only for internal use. I apologize for doing it so lately.

In your case, If I can add support for injecting services into a view in ASP.NET Core, would that class still be necessary to be public?

I suppose not. I needed it as public because I was still using it in my own RazorTemplateEngine. Once you made it internal - I could no longer use it. So now basically I made my own (albeit based on what you made). So now I have both RazorTemplateEngine and RazorViewToStringRenderer as part of my project. You could say I do not really need your nuget, but if you are going to fix it so DI is available, I will probably keep it. On a side note - did you figure out how _ViewImports.cshtml can be used with the templates?

I've added example for _ViewImports.cshtml. You can check it out here ce1696d

Released new pre-release version to NuGet https://github.com/soundaranbu/RazorTemplating/releases/tag/v1.4.0-rc.1

Try it out & let me know. Thanks!

Thanks for your great work. I tried your nuget and with just additional wrapper on top of your static RazorTemplateEngine I was able to switch very fast. Although I am not a big fan of static classes, I think I can live with it in this case. Unless it becomes a pain during tests.
The _ViewImports.cshtml example seems trivial and I thought I tried it, but it did not work for me. Probably made some kind of stupid mistake. I will close this thread as you have solved all my issues. Thanks again.

Glad it worked. Thanks! Keep Supporting :)