Blazor/Razor Class Library. Dependency Injection - blazor-webassembly

I am confused on how to use a Razor Class Library that requires injected objects.
I created a new razor class library project.
There is no program.cs file and hence no WebAssemblyHostBuilder to add services to?
How do I inject dependencies into the components?

A library is simply that. It's not an application. You load the DI objects in the application project. You can write extension classes in your library as a wrapper to load all the necessary objects. builder.Services.AddServerSideBlazor() is just such an extension.
Here's an example extension method for the Weather Forecast.
public static class ServiceCollectionExtensions
{
public static void AddWeatherServices(this IServiceCollection services)
{
services.AddSingleton<WeatherForecastService>();
}
}
And use it in the application startup:
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddWeatherServices();
You inject the services into your components as normal. If you use a component in an application and the necessary services aren't loaded the page on which the component is being used will throw an error.

Related

System.Net.Http not found in net core 2.0 class library

I have the following structure of my net core solution.
API - web api
Interfaces - class library
Implementation - class library
Models - class library
In the API startup.cs, I have registered the service like so:
services.AddHttpClient();
I have a class as such in the Implementation Project
using System.Net.Http;
public IHttpClientFactory ihttpClientFactory;
public class FooImplementation: IFoo {
public void someFooMethod(){
// here call client to fetch data from api
// process this data
}
}
I wanted to inject a IHttpClientFactory into this, however it is complaining that it cannot be found. How can I resolve this error? and Also, Is this the correct approach to pass IHttpClientFactory into this class library based on the project structure?
You do have to check the documentation of IHttpClientFactory carefully, which says,
Namespace: System.Net.Http
Assembly: Microsoft.Extensions.Http.dll
That's the hint on which NuGet package to use, so you should add a package reference to Microsoft.Extensions.Http.

StructureMap and classes that cannot accept constructor arguments

I have a ASP.NET web application (not MVC) which is actually a CMS application. I'm trying to set up StructureMap IoC framework and it's working well, but I've now hit a blocker in my understanding.
In my understanding, StructureMap enforces a pattern where all dependencies are registered in the core application assembly, so underlying assemblies do not themselves have a dependency on StructureMap.
So, say my application is My.App and it references another assembly My.Logic. My dependencies are all registered in a Container in My.App. This means that a class in My.Logic can take injected dependencies using a constructor like this:
public class Foo
{
private readonly IBar bar;
public Foo(IBar bar)
{
this.bar = bar;
}
}
But now I have a case where my class in My.Logic is a type which must be registered in the CMS, and this requires that it has an empty constructor.
So the problem is, if I can't inject using constructor parameters, and My.Logic doesn't have a dependency on My.App so I don't have access to the IoC container, is it possible to use StructureMap to handle this scenario?
If not, what alternative do I have other than create the class within the same assembly as the IoC container?
Use setter injection. See here
For<IBar>().Use<MyBar>();
Policies.FillAllPropertiesOfType<IBar>();

Customize Swagger Document Generation

I Have a spring boot application with following config.
#Configuration
#EnableWebMvc
#ComponentScan({ "com.xxx.mypackages" })
public class MyWebAppConfiguration extends WebMvcConfigurerAdapter {
}
In my project I have some web services and spring controllers. I want swagger to be enabled only in my web service classes. Currently, it generates documentation for both rest and controller classes. How can I customize that?
I'm using following dependency in gradle.
compile "com.mangofactory:swagger-springmvc:1.0.2"
If you look at the 1.0.2 documentation you'll find that SwaggerSpringMvcPlugin has a includePatterns method. This method takes a regular expression of the paths to include. For e.g. if you had an path prefix for the rest endpoints like this /rest/some-resource.... you could include a pattern, something like the snippet shown below
#Bean
public SwaggerSpringMvcPlugin customImplementation(){
return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
//... more config goes here
//regex to identify your rest services path
.includePatterns(".*rest.*");
}
Also it would be useful to know that we're going to be releasing 2.0 shortly with support for swagger spec 2.0. That might be something to consider as well.

Adding bindings in a test project with Ninject.MVC3

I'm having trouble figuring out what the best approach is these days for Ninject and ASP.NET MVC 3.
I have used Install-Package Ninject.MVC3 on my application and have my bootstrap class with the following methods:
public static void Start()
public static void Stop()
private static IKernel CreateKernel()
private static void RegisterServices(IKernel kernel)
It's all great and it loads my modules as expected. But historically what I have done is something like this:
MyApp.dll
Kernel.Bind<ISomething>().To<Something>();
Kernel.Bind<IBlah>().To<Blah>();
Kernel.Bind<IFoo>().To<Foo>();
MyApp.Tests.dll
Here I want to override ONLY ISomething's binding, so I used to just unbind the thing I needed to mock/whatever and rebind:
Kernel.Unbind<ISomething>();
Kernel.Bind<ISomethig>().To<TestSomething>();
But there isn't a method in the Nuget package that implies a thought through way to achieve this with the App_Start class from the original library. If I put another Ninject bootstrap class in my test app it only seems geared up to build a new kernel:
[assembly: WebActivator.PreApplicationStartMethod(typeof(TestNinjectBootstrapper), "Configure")]
I could store the kernel in the original bootstrapper statically and call from the tests project, but this feels wrong. Am I thinking too much and missing something? Or thinking too little :)
Argh. What is a good approach?
To reuse interface/class mapping registration in different project there is ability to create NInject modules. Modules just need to implement the INinjectModule interface, but most should extend the NinjectModule class for simplicity.
So you can place interface/class mapping inside module like in the following example:
public class WarriorModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<Sword>();
Bind<Samurai>().ToSelf().InSingletonScope();
}
}
After you define such module you can instantiate Kernel with mapping defined in this module.
All that you need is to specify this module as argument during creating Kernel object:
IKernel kernel = new StandardKernel(new WarriorModule());
Note that you can create and instantiate kernel with multiple modules.
So, modules will help you to reuse default mapping configuration. Mapping configuration will be defined in one place which will simplify maintance especially if there are several projects which uses the same interface/class mapping configuration.
There are also some other features like 'Dynamic Module Loading' and etc. More information about modules can be found here.

Using Microsoft Unity 2.0 framework with a web application

When using Unity 2.0 for dependency injection within a web application, it appears that user controls, pages, etc will all need make explicit calls to retrieve the container and "fetch" the dependencies … so using the annotations like [dependency] won't offer any value. This is likely since the location of the container (application context, http context cache, etc.) is unknown in the web configuration.
Since Unity itself provides method interception, isn't there a way to "tell" unity how to fetch the container correctly when you build your own web application? Rather than having to create base classes for page, etc.?
The problem is that the WebForms Pages and Controls are not set up to allow for construction by dependency injection, so Unity never gets invoked at all unless the class invokes Unity itself. I've found the best pattern in these cases is to invoke the DI framework in the constructor via a Service Locator and then use annotations to mark dependency properties. Something like this:
public MyPage()
{
// Injector is a wrapper class so you can change the underlying DI framework
// later if necessary.
Injector.Inject(this);
}
[Dependency]
public SomeService MyService {get;set;}

Resources