Skip to content

Instantly share code, notes, and snippets.

@cwe1ss
Last active November 25, 2021 10:57
Show Gist options
  • Select an option

  • Save cwe1ss/050a531e2711f5b62ab0 to your computer and use it in GitHub Desktop.

Select an option

Save cwe1ss/050a531e2711f5b62ab0 to your computer and use it in GitHub Desktop.

Revisions

  1. cwe1ss revised this gist Feb 6, 2016. 1 changed file with 11 additions and 0 deletions.
    11 changes: 11 additions & 0 deletions Startup.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    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>();
    }
  2. cwe1ss created this gist Feb 6, 2016.
    84 changes: 84 additions & 0 deletions WindsorRegistration.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    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;
    }
    }
    }
    39 changes: 39 additions & 0 deletions WindsorServiceProvider.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    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;
    }
    }
    }
    26 changes: 26 additions & 0 deletions WindsorServiceScope.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    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();
    }
    }
    }
    20 changes: 20 additions & 0 deletions WindsorServiceScopeFactory.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@
    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);
    }
    }
    }