Exporting
IHandlerBase can be exported as field.
public class Module1
{
/// <summary>Singleton</summary>
public static Module1 Instance { get; } = new();
/// <summary>Export handler</summary>
public TypeHandler typeHandler = new TypeHandler();
/// <summary>Export pre-build action (Invoked only with IHostBuilder)</summary>
public Action<IServiceBuilder> PreBuildAction = (IServiceBuilder sb) => WriteLine("DI Pre-Build");
/// <summary>Export post-build action (Invoked only with IHostBuilder)</summary>
public Func<IService, IService> PostBuildAction = (IService service) => { WriteLine("DI Post-Build"); return service; };
}
[Export<IHandlerBase>] can be attached on classes to be exported. The module must inherit IImportsAssembly<Module> to indicate that the assembly is to be scanned for exported classes.
[Export<IHandlerBase>, Order(1000)]
public class TypeHandler : IHandler<string, Type>
{
public void Handle(IQuery<string, Type> query)
{
// Already handled
if (query.Handled()) return;
// Find type
Type? type = Type.GetType(query.Request);
// No type found
if (type == null) return;
// Assign result
query.Response.SetValue(type);
}
}
public class Module2 : IImportsAssembly<Module2>
{
public static Module2 Instance { get; } = new();
}
Importing to IServiceBuilder
IServiceBuilder can process module.
// Initialize service builder
IServiceBuilder serviceBuilder = new ServiceBuilder();
serviceBuilder.HandlerSources.Add(Module2.Instance);
// Build service
IService service = serviceBuilder.Build();
// Query
Type type = service.GetRequired<string, Type>("System.String");
Console.WriteLine(type.FullName);
Services.Create() can process module.
// Build service
IService service = Services.Create(Module2.Instance);
// Query
Type type = service.GetRequired<string, Type>("System.String");
Console.WriteLine(type.FullName);
ModuleImport<IHandlerBase>.Cached[module] scans for IHandlerBase. It doesn't follow dependencies.
IHandlerBase[] handlers = ModuleImport<IHandlerBase>.Cached[Module2.Instance];
ServiceDescriptorInfo[] serviceDescriptors = ModuleImportServiceDescriptorInfo.Cached[Module2.Instance];
IHandlerBase[] serviceHandlers = serviceDescriptors.Select(sd => sd.ToHandler()).ToArray();
ModuleImportServiceDescriptorInfo.Cached[module] scans for [ServiceDescriptor] annotations.
ServiceDescriptorInfo[] serviceDescriptors = ModuleImportServiceDescriptorInfo.Cached[Module2.Instance];
IHandlerBase[] serviceHandlers = serviceDescriptors.Select(sd => sd.ToHandler()).ToArray();
Importing to IHostBuilder
HostingContainer.ModuleImportCached[Module.Instance] scans ServiceDescriptors and pre- and post-build actions.
// Initialize host builder
IHostBuilder hostBuilder = new HostBuilder();
hostBuilder.UseServiceProviderFactory(HostServiceProviderFactory.Instance);
HostingContainer.ModuleImportCached[Module1.Instance].WriteTo(hostBuilder);
HostingContainer.ModuleImportCached[Module2.Instance].WriteTo(hostBuilder);
// Build host
IHost host = hostBuilder.Build();
// Query service
IService service = host.Services.GetRequiredService<IService>();
Type type = service.GetRequired<string, Type>("System.String");
Console.WriteLine(type.FullName);
Full Example
Full example
using Avalanche.Hosting;
using Avalanche.Module;
using Avalanche.Service;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using static System.Console;
public class servicebuilder
{
public static void Run()
{
{
// <01>
// Initialize service builder
IServiceBuilder serviceBuilder = new ServiceBuilder();
serviceBuilder.HandlerSources.Add(Module2.Instance);
// Build service
IService service = serviceBuilder.Build();
// Query
Type type = service.GetRequired<string, Type>("System.String");
Console.WriteLine(type.FullName);
// </01>
}
{
// <02>
// Build service
IService service = Services.Create(Module2.Instance);
// Query
Type type = service.GetRequired<string, Type>("System.String");
Console.WriteLine(type.FullName);
// </02>
}
{
// <03>
IHandlerBase[] handlers = ModuleImport<IHandlerBase>.Cached[Module2.Instance];
ServiceDescriptorInfo[] serviceDescriptors = ModuleImportServiceDescriptorInfo.Cached[Module2.Instance];
IHandlerBase[] serviceHandlers = serviceDescriptors.Select(sd => sd.ToHandler()).ToArray();
// </03>
}
{
// <04>
ServiceDescriptorInfo[] serviceDescriptors = ModuleImportServiceDescriptorInfo.Cached[Module2.Instance];
IHandlerBase[] serviceHandlers = serviceDescriptors.Select(sd => sd.ToHandler()).ToArray();
// </04>
}
{
// <11>
// Initialize host builder
IHostBuilder hostBuilder = new HostBuilder();
hostBuilder.UseServiceProviderFactory(HostServiceProviderFactory.Instance);
HostingContainer.ModuleImportCached[Module1.Instance].WriteTo(hostBuilder);
HostingContainer.ModuleImportCached[Module2.Instance].WriteTo(hostBuilder);
// Build host
IHost host = hostBuilder.Build();
// Query service
IService service = host.Services.GetRequiredService<IService>();
Type type = service.GetRequired<string, Type>("System.String");
Console.WriteLine(type.FullName);
// </11>
}
}
// <98>
public class Module1
{
/// <summary>Singleton</summary>
public static Module1 Instance { get; } = new();
/// <summary>Export handler</summary>
public TypeHandler typeHandler = new TypeHandler();
/// <summary>Export pre-build action (Invoked only with IHostBuilder)</summary>
public Action<IServiceBuilder> PreBuildAction = (IServiceBuilder sb) => WriteLine("DI Pre-Build");
/// <summary>Export post-build action (Invoked only with IHostBuilder)</summary>
public Func<IService, IService> PostBuildAction = (IService service) => { WriteLine("DI Post-Build"); return service; };
}
// </98>
// <99>
[Export<IHandlerBase>, Order(1000)]
public class TypeHandler : IHandler<string, Type>
{
public void Handle(IQuery<string, Type> query)
{
// Already handled
if (query.Handled()) return;
// Find type
Type? type = Type.GetType(query.Request);
// No type found
if (type == null) return;
// Assign result
query.Response.SetValue(type);
}
}
public class Module2 : IImportsAssembly<Module2>
{
public static Module2 Instance { get; } = new();
}
// </99>
}