I would like to use Assembly Scanner Pattern and register class with Attribute from another assembly
Project: AssemblyScanner
using System;
namespace AssemblyScanner
{
public class RegisterScope : Attribute
{
public RegisterScope()
{
}
}
}
Project: Domian.Service
namespace Domain.Service.Test
{
[RegisterScope]
public class CarService
{
}
}
Project: UnitTests
using AssemblyScanner;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Domain.Service.Test;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Xunit;
namespace UnitTests
{
public class AssemblyScannerTests
{
[Fact]
public void AssemblyScannerTest()
{
var t = AssemblyScannerPattern().GetService<CarService>();
//AssemblyScannerPattern -> https://stackoverflow.com/questions/33811015/autofac-how-to-load-assemblies-that-are-referenced-but-not-directly-used
//Other Example -> https://www.codeproject.com/Articles/1201502/Dependency-Injection-in-ASP-NET-Web-API-using-Auto
}
public AutofacServiceProvider AssemblyScannerPattern()
{
var serviceCollection = new ServiceCollection();
ContainerBuilder builder = new ContainerBuilder();
string[] assemblyScanerPattern = new[] { @"Domain.Service*.dll" };
// Make sure process paths are sane...
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
// begin setup of autofac >>
// 1. Scan for assemblies containing autofac modules in the bin folder
List<Assembly> assemblies = new List<Assembly>();
assemblies.AddRange(
Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.dll", SearchOption.AllDirectories)
.Where(filename => assemblyScanerPattern.Any(pattern => Regex.IsMatch(filename, pattern)))
.Select(Assembly.LoadFrom)
);
foreach (var assembly in assemblies)
{
builder.RegisterAssemblyTypes(assembly)
.AsImplementedInterfaces();
}
foreach (var assembly in assemblies)
{
foreach (var attributeClass in assembly.ExportedTypes)
{
foreach (var registerScope in attributeClass.CustomAttributes.Where(s => s.AttributeType.Name.Contains("RegisterScope")))
{
var importedClassFromAssembly = GetInstance(attributeClass.Namespace + "." + attributeClass.Name);
//builder.RegisterType<importedClassFromAssembly.GetType>().As(importedClassFromAssembly);
}
}
}
var container = builder.Build();
var serviceProvider = new AutofacServiceProvider(container);
return serviceProvider;
}
public object GetInstance(string strFullyQualifiedName)
{
Type type = Type.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
type = asm.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
}
return null;
}
}
}
I found class with Attribute "RegisterScope" but I have got problem with builder.RegisterType
And here I get null but I would like to get instance class
Update
It`s better situation I get now correct object when I write this
builder.RegisterInstance(importedClassFromAssembly).As<CarService>();
but I would like to something like this - Error
builder.RegisterInstance(importedClassFromAssembly).As<importedClassFromAssembly.GetType>();
I try also this (but this give me null in GetService();)
builder.RegisterInstance(importedClassFromAssembly).As<dynamic>();
Current Code with Last small problem
using AssemblyScanner;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Domain.Service.Test;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Xunit;
namespace UnitTests
{
public class AssemblyScannerTests
{
[Fact]
public void AssemblyScannerTest()
{
var t = AssemblyScannerPattern().GetService<CarService>();
//AssemblyScannerPattern -> https://stackoverflow.com/questions/33811015/autofac-how-to-load-assemblies-that-are-referenced-but-not-directly-used
//Other Example -> https://www.codeproject.com/Articles/1201502/Dependency-Injection-in-ASP-NET-Web-API-using-Auto
}
public AutofacServiceProvider AssemblyScannerPattern()
{
var serviceCollection = new ServiceCollection();
ContainerBuilder builder = new ContainerBuilder();
string[] assemblyScanerPattern = new[] { @"Domain.Service*.dll" };
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
List<Assembly> assemblies = new List<Assembly>();
assemblies.AddRange(
Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.dll", SearchOption.AllDirectories)
.Where(filename => assemblyScanerPattern.Any(pattern => Regex.IsMatch(filename, pattern)))
.Select(Assembly.LoadFrom)
);
foreach (var assembly in assemblies)
{
foreach (var attributeClass in assembly.ExportedTypes)
{
if(attributeClass.CustomAttributes.Where(s => s.AttributeType.Name.Contains("RegisterScope")).Any())
{
var importedClassFromAssembly = GetInstance(attributeClass.FullName);
builder.RegisterInstance(importedClassFromAssembly).As<CarService>();
}
}
}
var container = builder.Build();
var serviceProvider = new AutofacServiceProvider(container);
return serviceProvider;
}
public object GetInstance(string strFullyQualifiedName)
{
Type type = Type.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
type = asm.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
}
return null;
}
}
}