К сожалению, не существует элегантного способа сделать то, что вы хотите.Контейнер Autofac и его конструктор являются «черными ящиками», которые не позволяют вам хорошо рассмотреть то, что у вас уже есть.
При двойной регистрации компонента нет вреда, ЕСЛИ БЕЗ ваших регистраций не выполнено-зависимый (BAD, BAD, BAD).Повторная регистрация просто перезапишет старую регистрацию новой.
Я серьезно подвергаю сомнению этот код, поскольку он полностью зависит от того, как инициализируется allTypesInAllAvailableAssemblies.Если это действительно каждый тип в вашей системе, то это дерьмовая стрельба относительно того, что решит, скажем, IDisposable.Если у вас есть несколько различных реализаций, скажем, IConfigurator, вы будете иметь ограниченный контроль над тем, какая из них в итоге будет зарегистрирована, независимо от того, проверяете ли вы то, что уже зарегистрировано, или просто перезаписываете регистрацию;это полностью зависит от того, какой класс окажется первым (или последним) в списке.
Единственное, что я мог подумать, это использовать небольшой Linq, чтобы убедиться, что список типов, которые вы регистрируете, уникален:
protected override void Load(ContainerBuilder builder)
{
foreach (var componentType in allTypesInAllAvailableAssemblies.OfType<Type>().Distinct()) // Set elsewhere
{
var handlerInterfaces = componentType.GetInterfaces().Where(i => i.IsClosedTypeOf(typeof(IMessageHandler<>)));
if (handlerInterfaces.Any())
builder.RegisterType(componentType).As(handlerInterfaces);
}
}
Это гарантирует, что каждый экземпляр componentType никогда не был замечен сборщиком ранее, в рамках этого цикла foreach.Это означает, что, учитывая, что это единственный модуль, используемый для создания контейнеров, и каждый контейнер создается только один раз и никогда не обновляется, каждый компонент в системе будет зарегистрирован в любом данном контейнере ровно один раз.Общие интерфейсы, такие как IDisposable, IEnumerable, IComparable, IComparer и т. Д., Будут бесполезны для решения;они будут преобразованы в экземпляр последнего класса, у которого был этот интерфейс.
Если вам нужно убедиться, что интерфейс никогда не был зарегистрирован или этот код также работает при использовании ContainerBuilder для Update () исуществующий контейнер, просто остановите то, что вы делаете, потому что вы собираетесь создать безнадежный беспорядок, который вы никогда не сможете поддерживать должным образом.