Я хочу загрузить все типы из сборки и зарегистрировать их для инъекции зависимости, используя следующий метод, тяжелый отражение: < /p>
using System.Reflection;
namespace Server
{
public static class AddServices
{
public static IServiceCollection AddRepositories(this IServiceCollection services)
{
Assembly.Load("Services")
.GetTypes()
.Where(a => !a.IsAbstract && !a.IsInterface)
.Select(a => new { assignedType = a, serviceTypes = a.GetInterfaces() })
.ToList()
.ForEach(typeToRegister =>
{
if (typeToRegister.serviceTypes.Length != 1)
return;
services.AddScoped(typeToRegister.serviceTypes[0], typeToRegister.assignedType);
});
return services;
}
}
}
< /code>
Это гарантирует, что мне не нужно вручную регистрировать множество зависимостей (и вручную обновлять список каждый раз, когда я создаю новую зависимость). Это правда, что это не обрабатывает сценарий, в котором зависимость реализует несколько интерфейсов. Например, зависимость, которая реализует как iRepository , так и Idisposable , будет проигнорирована этим методом. Но не сложно добавить отрицатель интерфейсов, которые игнорируются этим методом (например, Idisposable ).
Мой код не имеет таких зависимостей, поэтому у него нет отрицателя.using Dto.Interfaces;
namespace Services
{
public interface IRepository
{
public Task Calculate(List list)
where T : ICommonProps;
}
public class Repository : IRepository
{
public async Task Calculate(List list)
where T : ICommonProps
{
// implementation irrelevant
await Task.Delay(100);
foreach (var thing in list)
{
Console.WriteLine(thing);
}
return 0m;
}
}
}
< /code>
Внезапно программа срабатывается во время запуска со следующим странным сообщением об ошибке: < /p>
не может создать экземпляр типа реализации 'dotneteightfeaturetesting.server.services.repository+d__0`1 [t]' для типа службы. 'System.runtime.compilerservices.iasyncstatemachine' < /p>
< /blockquote>
Это связано именно с тем, как работает структура задачи, и не имеет значения для разработчиков API, как я. Вы можете легко обойти эту проблему, изменив код, чтобы не использовать задачи, но это совершенно непригодно для производственного API..Where(a => !a.IsAbstract && !a.IsInterface && !a.IsGenericType)
Но это не подходит для любого, кто на самом деле имеет общие зависимости, зарегистрированные в их приложении. не хочу совета о том, как я мог изменить API. Это упрощенный пример, в котором отсутствуют все мои промежуточные программные слои. Кроме того, постарайтесь не заблудиться в сорняках, размышляя обо всех возможных сценариях инъекции зависимости; Сосредоточьтесь на наиболее распространенных. Он использует 3 проекта в одном решении, с именем сервера, служб и DTO. Структура папок может быть выведена из пространств имен. Ссылки на серверы службы и DTO, и сервисы ссылки DTO (это требуется для минимального воспроизводимого примера, в противном случае метод AddRepositories найдет кучу дополнительного мусора).
Программа:
using Server;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRepositories()
.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
< /code>
dto.interfaces:
namespace Dto.Interfaces
{
public interface ICommonProps
{
long Id { get; }
string Name { get; }
}
}
< /code>
dto: < /p>
using Dto.Interfaces;
namespace Dto
{
public record Company(long Id, string Name, string TaxCode) : ICommonProps
{
public override string ToString() => $"{Id} {Name}: {TaxCode}";
}
public record Person(long Id, string Name, DateTimeOffset Birthday) : ICommonProps
{
public override string ToString() => $"{Id} {Name}: {Birthday}";
}
}
< /code>
контроллеры: < /p>
using Microsoft.AspNetCore.Mvc;
using Dto;
using Services;
namespace Server.Controllers
{
[ApiController]
[Route("[controller]")]
public class FlexibleController : ControllerBase
{
private readonly IRepository _repository;
public FlexibleController(IRepository repository)
{
_repository = repository;
}
[HttpPost(nameof(CalculateForPeople))]
public async Task CalculateForPeople([FromForm] List people)
{
return await _repository.Calculate(people);
}
[HttpPost(nameof(CalculateForCompanies))]
public async Task CalculateForCompanies([FromForm] List companies)
{
return await _repository.Calculate(companies);
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... hod-return
.NET 8 Внедрение зависимостей с использованием отражения: служба с общим методом возвращающего задания <> ⇐ C#
Место общения программистов C#
1753159781
Anonymous
Я хочу загрузить все типы из сборки и зарегистрировать их для инъекции зависимости, используя следующий метод, тяжелый отражение: < /p>
using System.Reflection;
namespace Server
{
public static class AddServices
{
public static IServiceCollection AddRepositories(this IServiceCollection services)
{
Assembly.Load("Services")
.GetTypes()
.Where(a => !a.IsAbstract && !a.IsInterface)
.Select(a => new { assignedType = a, serviceTypes = a.GetInterfaces() })
.ToList()
.ForEach(typeToRegister =>
{
if (typeToRegister.serviceTypes.Length != 1)
return;
services.AddScoped(typeToRegister.serviceTypes[0], typeToRegister.assignedType);
});
return services;
}
}
}
< /code>
Это гарантирует, что мне не нужно вручную регистрировать множество зависимостей (и вручную обновлять список каждый раз, когда я создаю новую зависимость). Это правда, что это не обрабатывает сценарий, в котором зависимость реализует несколько интерфейсов. Например, зависимость, которая реализует как iRepository , так и Idisposable , будет проигнорирована этим методом. Но не сложно добавить отрицатель интерфейсов, которые игнорируются этим методом (например, Idisposable ).
Мой код не имеет таких зависимостей, поэтому у него нет отрицателя.using Dto.Interfaces;
namespace Services
{
public interface IRepository
{
public Task Calculate(List list)
where T : ICommonProps;
}
public class Repository : IRepository
{
public async Task Calculate(List list)
where T : ICommonProps
{
// implementation irrelevant
await Task.Delay(100);
foreach (var thing in list)
{
Console.WriteLine(thing);
}
return 0m;
}
}
}
< /code>
Внезапно программа срабатывается во время запуска со следующим странным сообщением об ошибке: < /p>
не может создать экземпляр типа реализации 'dotneteightfeaturetesting.server.services.repository+d__0`1 [t]' для типа службы. 'System.runtime.compilerservices.iasyncstatemachine' < /p>
< /blockquote>
Это связано именно с тем, как работает структура задачи, и не имеет значения для разработчиков API, как я. Вы можете легко обойти эту проблему, изменив код, чтобы не использовать задачи, но это совершенно непригодно для производственного API..Where(a => !a.IsAbstract && !a.IsInterface && !a.IsGenericType)
Но это не подходит для любого, кто на самом деле имеет общие зависимости, зарегистрированные в их приложении. [b] не [/b] хочу совета о том, как я мог изменить API. Это упрощенный пример, в котором отсутствуют все мои промежуточные программные слои. Кроме того, постарайтесь не заблудиться в сорняках, размышляя обо всех возможных сценариях инъекции зависимости; Сосредоточьтесь на наиболее распространенных. Он использует 3 проекта в одном решении, с именем сервера, служб и DTO. Структура папок может быть выведена из пространств имен. Ссылки на серверы службы и DTO, и сервисы ссылки DTO (это требуется для минимального воспроизводимого примера, в противном случае метод AddRepositories найдет кучу дополнительного мусора).
Программа:
using Server;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRepositories()
.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
< /code>
dto.interfaces:
namespace Dto.Interfaces
{
public interface ICommonProps
{
long Id { get; }
string Name { get; }
}
}
< /code>
dto: < /p>
using Dto.Interfaces;
namespace Dto
{
public record Company(long Id, string Name, string TaxCode) : ICommonProps
{
public override string ToString() => $"{Id} {Name}: {TaxCode}";
}
public record Person(long Id, string Name, DateTimeOffset Birthday) : ICommonProps
{
public override string ToString() => $"{Id} {Name}: {Birthday}";
}
}
< /code>
контроллеры: < /p>
using Microsoft.AspNetCore.Mvc;
using Dto;
using Services;
namespace Server.Controllers
{
[ApiController]
[Route("[controller]")]
public class FlexibleController : ControllerBase
{
private readonly IRepository _repository;
public FlexibleController(IRepository repository)
{
_repository = repository;
}
[HttpPost(nameof(CalculateForPeople))]
public async Task CalculateForPeople([FromForm] List people)
{
return await _repository.Calculate(people);
}
[HttpPost(nameof(CalculateForCompanies))]
public async Task CalculateForCompanies([FromForm] List companies)
{
return await _repository.Calculate(companies);
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79709104/net-8-dependency-injection-using-reflection-service-with-generic-method-return[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия