Skip to content

Castle.Windsor DI container [Working code] #263

Description

@egorpavlikhin

If anyone is interested I've adapted current autofac code to work with Castle.Windsor container. Can't be bothered to do an official pull request, so here it goes.

public static class WindsorRegistration
{
    public static void Populate(
            this IWindsorContainer container,
            IEnumerable<IServiceDescriptor> descriptors)
    {
        container.Register(Component.For<IWindsorContainer>().Instance(container));
        container.Register(Component.For<IServiceProvider>().ImplementedBy<WindsorServiceProvider>());
        container.Register(Component.For<IServiceScopeFactory>().ImplementedBy<WindsorServiceScopeFactory>());

        container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel));

        Register(container, descriptors);
    }

    private static void Register(
            IWindsorContainer container,
            IEnumerable<IServiceDescriptor> descriptors)
    {
        foreach (var descriptor in descriptors)
        {
            if (descriptor.ImplementationType != null)
            {
                // Test if the an open generic type is being registered
                var serviceTypeInfo = descriptor.ServiceType.GetTypeInfo();
                if (serviceTypeInfo.IsGenericTypeDefinition)
                {
                    container.Register(Component.For(descriptor.ServiceType)
                                            .ImplementedBy(descriptor.ImplementationType)
                                            .ConfigureLifecycle(descriptor.Lifecycle)
                                            .OnlyNewServices());
                }
                else
                {
                    container.Register(Component.For(descriptor.ServiceType)
                                            .ImplementedBy(descriptor.ImplementationType)
                                            .ConfigureLifecycle(descriptor.Lifecycle)
                                            .OnlyNewServices());
                }
            }
            else if (descriptor.ImplementationFactory != null)
            {
                var service1 = descriptor;
                container.Register(Component.For(descriptor.ServiceType)
                        .UsingFactoryMethod<object>(c =>
                        {
                            var builderProvider = container.Resolve<IServiceProvider>();
                            return
                                service1.ImplementationFactory(builderProvider);
                        })
                        .ConfigureLifecycle(descriptor.Lifecycle)
                        .OnlyNewServices());
            }
            else
            {
                container.Register(Component.For(descriptor.ServiceType)
                        .Instance(descriptor.ImplementationInstance)
                        .ConfigureLifecycle(descriptor.Lifecycle)
                        .OnlyNewServices());
            }
        }
    }

    private static ComponentRegistration<object> ConfigureLifecycle(
            this ComponentRegistration<object> registrationBuilder,
            LifecycleKind lifecycleKind)
    {
        switch (lifecycleKind)
        {
            case LifecycleKind.Singleton:
                registrationBuilder.LifestyleSingleton();
                break;
            case LifecycleKind.Scoped:
                registrationBuilder.LifestyleScoped();
                break;
            case LifecycleKind.Transient:
                registrationBuilder.LifestyleTransient();
                break;
        }

        return registrationBuilder;
    }

    private class WindsorServiceProvider : IServiceProvider
    {
        private readonly IWindsorContainer _container;

        public WindsorServiceProvider(IWindsorContainer container)
        {
            _container = container;
        }

        public object GetService(Type serviceType)
        {
            return _container.Resolve(serviceType);
        }
    }

    private class WindsorServiceScopeFactory : IServiceScopeFactory
    {
        private readonly IWindsorContainer _container;

        public WindsorServiceScopeFactory(IWindsorContainer container)
        {
            _container = container;
        }

        public IServiceScope CreateScope()
        {
            return new WindsorServiceScope(_container);
        }
    }

    private 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
        {
            get { return _serviceProvider; }
        }

        public void Dispose()
        {
            _scope.Dispose();
        }
    }
}

It fits in like this:

app.UseServices(services => {
            // Add EF services to the services container.
            services
                .AddEntityFramework(Configuration)
                .AddSqlServer()
                .AddDbContext<ApplicationDbContext>();

            // Add Identity services to the services container.
            services
                .AddIdentity<ApplicationUser, IdentityRole>(Configuration)
                .AddDefaultTokenProviders();

            // Add MVC services to the services container.
            services
                .AddMvc();

            container.Populate(services);

            container.BeginScope();

            return container.Resolve<IServiceProvider>();
        });

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions