Skip to content

Instantly share code, notes, and snippets.

@cwe1ss
Last active November 25, 2021 10:57
Show Gist options
  • Save cwe1ss/050a531e2711f5b62ab0 to your computer and use it in GitHub Desktop.
Save cwe1ss/050a531e2711f5b62ab0 to your computer and use it in GitHub Desktop.
Castle.Facilities.AspNetCoreIntegration
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Configure regular ASP.NET Core services
services.AddMvc();
// ...
// Send configuration to Castle Windsor
Container.Populate(services);
Container.BeginScope();
return Container.Resolve<IServiceProvider>();
}
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.Resolvers.SpecializedResolvers;
using Castle.Windsor;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
namespace Castle.Facilities.AspNetCoreIntegration
{
public static class WindsorRegistration
{
public static void Populate(this IWindsorContainer container,
IEnumerable<Microsoft.Extensions.DependencyInjection.ServiceDescriptor> descriptors)
{
container.Register(Component.For<IWindsorContainer>().Instance(container).OnlyNewServices());
container.Register(Component.For<IServiceProvider>().ImplementedBy<WindsorServiceProvider>());
container.Register(Component.For<IServiceScopeFactory>().ImplementedBy<WindsorServiceScopeFactory>());
// ASP.NET Core uses IEnumerable<T> to resolve a list of types.
// Since some of these types are optional, Windsor must also return empty collections.
container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel, allowEmptyCollections: true));
Register(container, descriptors);
}
private static void Register(IWindsorContainer container,
IEnumerable<Microsoft.Extensions.DependencyInjection.ServiceDescriptor> descriptors)
{
foreach (var descriptor in descriptors)
{
if (descriptor.ImplementationType != null)
{
container.Register(
Component.For(descriptor.ServiceType)
.ImplementedBy(descriptor.ImplementationType)
.ConfigureLifecycle(descriptor.Lifetime));
}
else if (descriptor.ImplementationFactory != null)
{
var service1 = descriptor;
container.Register(
Component.For(descriptor.ServiceType)
.UsingFactoryMethod(c =>
{
var serviceProvider = container.Resolve<IServiceProvider>();
return service1.ImplementationFactory(serviceProvider);
})
.ConfigureLifecycle(descriptor.Lifetime));
}
else
{
container.Register(
Component.For(descriptor.ServiceType)
.Named(descriptor.ServiceType.FullName)
.Instance(descriptor.ImplementationInstance)
.ConfigureLifecycle(descriptor.Lifetime));
}
}
}
private static ComponentRegistration<object> ConfigureLifecycle(
this ComponentRegistration<object> registrationBuilder,
ServiceLifetime serviceLifetime)
{
switch (serviceLifetime)
{
case ServiceLifetime.Singleton:
registrationBuilder.LifestyleSingleton();
break;
case ServiceLifetime.Scoped:
registrationBuilder.LifestyleScoped();
break;
case ServiceLifetime.Transient:
registrationBuilder.LifestyleTransient();
break;
}
return registrationBuilder;
}
}
}
using Castle.Windsor;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Castle.Facilities.AspNetCoreIntegration
{
public class WindsorServiceProvider : IServiceProvider
{
private readonly IWindsorContainer _container;
public WindsorServiceProvider(IWindsorContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
// ASP.NET uses GetService<IEnumerable<TDesiredType>>() to get a collection.
// This must be resolved to IWindsorContainer.ResolveAll();
var typeInfo = serviceType.GetTypeInfo();
if (typeInfo.IsGenericType && serviceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
var itemType = typeInfo.GenericTypeArguments[0];
return _container.ResolveAll(itemType);
}
// Microsoft.Extensions.DependencyInjection is built to handle optional registrations.
// However Castle Windsor throws ComponentNotFoundException when a type wasn't registered.
// For this reason we have to manually check if the type exists in Windsor.
if (_container.Kernel.HasComponent(serviceType))
{
return _container.Resolve(serviceType);
}
return null;
}
}
}
using Castle.MicroKernel.Lifestyle;
using Castle.Windsor;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Castle.Facilities.AspNetCoreIntegration
{
public class WindsorServiceScope : IServiceScope
{
private readonly IServiceProvider _serviceProvider;
private readonly IDisposable _scope;
public WindsorServiceScope(IWindsorContainer container)
{
_scope = container.BeginScope();
_serviceProvider = container.Resolve<IServiceProvider>();
}
public IServiceProvider ServiceProvider => _serviceProvider;
public void Dispose()
{
_scope.Dispose();
}
}
}
using Castle.Windsor;
using Microsoft.Extensions.DependencyInjection;
namespace Castle.Facilities.AspNetCoreIntegration
{
public class WindsorServiceScopeFactory : IServiceScopeFactory
{
private readonly IWindsorContainer _container;
public WindsorServiceScopeFactory(IWindsorContainer container)
{
_container = container;
}
public IServiceScope CreateScope()
{
return new WindsorServiceScope(_container);
}
}
}
Copy link

ghost commented Feb 24, 2016

great

@bluetianx
Copy link

ComponentRegistrationException:
I copy your code in my asp.net core

but An error occurred while starting the application.

ComponentRegistrationException: Component Microsoft.Extensions.Options.OptionsManager`1 could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name.
Castle.MicroKernel.SubSystems.Naming.DefaultNamingSubSystem.Register(IHandler handler)

ComponentRegistrationException: Component Microsoft.Extensions.Options.OptionsManager`1 could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name.
Castle.MicroKernel.SubSystems.Naming.DefaultNamingSubSystem.Register(IHandler handler)
Castle.MicroKernel.DefaultKernel.AddCustomComponent(ComponentModel model)
Castle.MicroKernel.Registration.ComponentRegistration.Castle.MicroKernel.Registration.IRegistration.Register(IKernelInternal kernel)
Castle.MicroKernel.DefaultKernel.Register(IRegistration[] registrations)
Castle.Windsor.WindsorContainer.Register(IRegistration[] registrations)
BlueBlog.Utility.WindsorRegistration.Register(IWindsorContainer container, IEnumerable descriptors) in WindsorRegistration.cs
+
container.Register(
BlueBlog.Utility.WindsorRegistration.Populate(IocContainer container, IEnumerable descriptors) in WindsorRegistration.cs
+
Register(container.Container, descriptors);
BlueBlog.Startup.ConfigureServices(IServiceCollection services) in Startup.cs
+
container.Populate(services);
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

@bluetianx
Copy link

How should I solve this error ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment