Я хотел бы использовать шаблон сканера сборки и зарегистрировать класс с атрибутом из другой сборки
Проект: AssemblyScanner
using System;
namespace AssemblyScanner
{
public class RegisterScope : Attribute
{
public RegisterScope()
{
}
}
}
Проект: 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;
}
}
}
Я нашел класс с атрибутом "RegisterScope", но у меня возникла проблема с builder.RegisterType
![enter image description here](https://i.stack.imgur.com/4q6HP.png)
И здесь я получаю ноль, но я хотел бы получить экземпляр класса
![enter image description here](https://i.stack.imgur.com/ASPW4.png)
Обновление
Это`Когда я пишу это
builder.RegisterInstance(importedClassFromAssembly).As<CarService>();
, я получаю правильный объект, но я хотел бы что-то вроде этого - Ошибка
builder.RegisterInstance(importedClassFromAssembly).As<importedClassFromAssembly.GetType>();
Я также пытаюсь это сделать (но это дает мне нольв GetService ();)
builder.RegisterInstance(importedClassFromAssembly).As<dynamic>();
Текущий код с последней небольшой проблемой
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;
}
}
}