New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asp.net core support #63

Closed
dv00d00 opened this Issue Jul 6, 2016 · 5 comments

Comments

6 participants
@dv00d00

dv00d00 commented Jul 6, 2016

Short version:
Any estimations on this one, really need this one, stops our solution from migrating to mvc core 1.0?

Long version:
I found nuget package which I had to decompile in order to resolve dependency to reflection dll. Managed to make it compile but it dies while trying to resolve IStringLocalizer. This interface has typed child IStringLocalizer and a typed concrete implementation which probably I not consume correctly.

Sorry for the wall of purely readable code, but this is all I managed to come up with by partially decompiling Unity-CoreClr 1.0.0-beta3

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

using Microsoft.Practices.Unity;
using Microsoft.Extensions.DependencyInjection;

public static class UnityGlueConfiguration
{
    public static void Register(IServiceCollection services, IUnityContainer container)
    {
        container.RegisterType<IServiceScopeFactory, ServiceScopeFactory>(Array.Empty<InjectionMember>());
        container.RegisterType<IServiceScope, ServiceScope>(Array.Empty<InjectionMember>());
        container.RegisterType<IServiceProvider, ServiceProvider>(Array.Empty<InjectionMember>());

        RegisterEnumerable(container);

        HashSet<Type> aggregateTypes = GetAggregateTypes(services);
        MethodInfo miRegisterInstanceOpen = RegisterInstance();
        Func<ServiceDescriptor, LifetimeManager> lifetime = GetLifetime();
        foreach (ServiceDescriptor service in services)
            RegisterType(container, lifetime, service, aggregateTypes, miRegisterInstanceOpen);
    }

    private static MethodInfo RegisterInstance()
    {
        return (TypeExtensions.GetMethods(typeof(UnityContainerExtensions), (BindingFlags)24))
            .Single(mi =>
                {
                    if (mi.Name == "RegisterInstance" && mi.IsGenericMethod)
                        return mi.GetParameters().Length == 4;
                    return false;
                });
    }

    private static HashSet<Type> GetAggregateTypes(IServiceCollection services)
    {
        return new HashSet<Type>(
            services.GroupBy(k => k.ServiceType, serviceDescriptor => serviceDescriptor)
            .Where(typeGrouping => typeGrouping.Count() > 1)
            .Select(type => type.Key));
    }

    private static void RegisterEnumerable(IUnityContainer _container)
    {
        _container.RegisterType(typeof(IEnumerable<>), new InjectionFactory((container, enumerableType, name) =>
            {
                Type type = TypeExtensions.GetGenericArguments(enumerableType).Single();
                IEnumerable<object> first = container.ResolveAll(type, Array.Empty<ResolverOverride>());
                object[] objArray;
                if (!_container.IsRegistered(type) && 
                        (TypeExtensions.GetGenericArguments(type).Length == 0 || 
                        !_container.IsRegistered(type.GetGenericTypeDefinition())))

                    objArray = new object[0];
                else
                    objArray = new object[1]
                    {
                        container.Resolve(type, Array.Empty<ResolverOverride>())
                    };

                object[] array = first.Concat(objArray).ToArray();

                return TypeExtensions
                    .GetMethod(typeof(Enumerable), "OfType", (BindingFlags)24)
                    .MakeGenericMethod(type).Invoke(null, new object[] { array });

            }) as InjectionMember);
    }

    private static Func<ServiceDescriptor, LifetimeManager> GetLifetime()
    {
        return serviceDescriptor =>
            {
                switch (serviceDescriptor.Lifetime)
                {
                    case ServiceLifetime.Singleton:
                        return (LifetimeManager)new ContainerControlledLifetimeManager();
                    case ServiceLifetime.Scoped:
                        return (LifetimeManager)new HierarchicalLifetimeManager();
                    case ServiceLifetime.Transient:
                        return (LifetimeManager)new TransientLifetimeManager();
                    default:
                        throw new NotImplementedException(string.Format("Unsupported lifetime manager type '{0}'", (object)serviceDescriptor.Lifetime));
                }
            };
    }

    private static void RegisterType(
        IUnityContainer _container,
        Func<ServiceDescriptor, LifetimeManager> fetchLifetime, 
        ServiceDescriptor serviceDescriptor,
        ICollection<Type> aggregateTypes,
        MethodInfo miRegisterInstanceOpen)
    {
        LifetimeManager lifetimeManager = fetchLifetime(serviceDescriptor);
        bool isAggregateType = aggregateTypes.Contains(serviceDescriptor.ServiceType);
        if (serviceDescriptor.ImplementationType != null)
            RegisterImplementation(_container, serviceDescriptor, isAggregateType, lifetimeManager);
        else if (serviceDescriptor.ImplementationFactory != null)
        {
            RegisterFactory(_container, serviceDescriptor, isAggregateType, lifetimeManager);
        }
        else
        {
            if (serviceDescriptor.ImplementationInstance == null)
                throw new InvalidOperationException("Unsupported registration type");
            RegisterSingleton(_container, serviceDescriptor, miRegisterInstanceOpen, isAggregateType, lifetimeManager);
        }
    }

    private static void RegisterImplementation(
        IUnityContainer _container,
        ServiceDescriptor serviceDescriptor,
        bool isAggregateType,
        LifetimeManager lifetimeManager)
    {
        if (isAggregateType)
            _container.RegisterType(serviceDescriptor.ServiceType, serviceDescriptor.ImplementationType, serviceDescriptor.ImplementationType.AssemblyQualifiedName, lifetimeManager, Array.Empty<InjectionMember>());
        else
            _container.RegisterType(serviceDescriptor.ServiceType, serviceDescriptor.ImplementationType, lifetimeManager, Array.Empty<InjectionMember>());
    }

    private static void RegisterFactory(
        IUnityContainer _container,
        ServiceDescriptor serviceDescriptor,
        bool isAggregateType,
        LifetimeManager lifetimeManager)
    {
        if (isAggregateType)

            _container.RegisterType(
                serviceDescriptor.ServiceType,
                serviceDescriptor.ImplementationType.AssemblyQualifiedName,
                lifetimeManager,
                new InjectionFactory(container => serviceDescriptor.ImplementationFactory(container.Resolve<IServiceProvider>(Array.Empty<ResolverOverride>()))));

        else
            _container.RegisterType(serviceDescriptor.ServiceType, lifetimeManager, 
                new InjectionFactory(container => serviceDescriptor.ImplementationFactory(container.Resolve<IServiceProvider>(Array.Empty<ResolverOverride>()))));
    }

    private static void RegisterSingleton(
        IUnityContainer container,
        ServiceDescriptor serviceDescriptor,
        MethodInfo miRegisterInstanceOpen,
        bool isAggregateType,
        LifetimeManager lifetimeManager)
    {
        if (isAggregateType)
        {
            Type type = typeof(string);

            if (serviceDescriptor.ImplementationType != null)
            {
                type = serviceDescriptor.ImplementationType;
            }
            else if (serviceDescriptor.ImplementationInstance != null)
            {
                type = serviceDescriptor.ImplementationInstance.GetType();
            }

            miRegisterInstanceOpen.MakeGenericMethod(serviceDescriptor.ServiceType)
                .Invoke(null, new object[4] { container, type.AssemblyQualifiedName, serviceDescriptor.ImplementationInstance, lifetimeManager });
        }
        else
        {
            container.RegisterInstance(serviceDescriptor.ServiceType, serviceDescriptor.ImplementationInstance, lifetimeManager);
        }
    }
}

public class ServiceProvider : IServiceProvider
{
    private readonly IUnityContainer container;

    public ServiceProvider(IUnityContainer container)
    {
        this.container = container;
    }

    public object GetService(Type serviceType)
    {
        return this.container.Resolve(serviceType, Array.Empty<ResolverOverride>());
    }
}

public class ServiceScope : IServiceScope, IDisposable
{
    private readonly IUnityContainer container;
    private readonly IServiceProvider serviceProvider;

    IServiceProvider IServiceScope.ServiceProvider => this.serviceProvider;

    public ServiceScope(IUnityContainer container)
    {
        this.container = container.CreateChildContainer();
        this.serviceProvider = this.container.Resolve<IServiceProvider>(Array.Empty<ResolverOverride>());
    }

    void IDisposable.Dispose()
    {
        this.container.Dispose();
    }
}

public class ServiceScopeFactory : IServiceScopeFactory
{
    private readonly IUnityContainer container;

    public ServiceScopeFactory(IUnityContainer container)
    {
        this.container = container;
    }

    IServiceScope IServiceScopeFactory.CreateScope()
    {
        return this.container.Resolve<IServiceScope>(Array.Empty<ResolverOverride>());
    }
}

@Legends

This comment has been minimized.

Show comment
Hide comment
@Legends

Legends Jul 7, 2016

@woodp, When will Unity support ASP.NET Core 1.0?

Legends commented Jul 7, 2016

@woodp, When will Unity support ASP.NET Core 1.0?

@cordasfilip

This comment has been minimized.

Show comment
Hide comment
@cordasfilip

cordasfilip Oct 1, 2016

Someone has some info?

cordasfilip commented Oct 1, 2016

Someone has some info?

@napalm684

This comment has been minimized.

Show comment
Hide comment
@napalm684

napalm684 Oct 17, 2016

I asked Jeff Fritz at a Dotnet meetup and he was not aware of any efforts to bring Unity IOC forward to core. The team has largely been dispersed throughout Microsoft. For what it's worth I'd like to see it get picked up/migrated myself.

napalm684 commented Oct 17, 2016

I asked Jeff Fritz at a Dotnet meetup and he was not aware of any efforts to bring Unity IOC forward to core. The team has largely been dispersed throughout Microsoft. For what it's worth I'd like to see it get picked up/migrated myself.

@tommed

This comment has been minimized.

Show comment
Hide comment
@tommed

tommed Dec 2, 2016

We gave up on Unity have started using structuremap instead which does support dotnet core.
It's a sad day when a library you know, love and use throughout your projects grows cobwebs, but there are other, more active efforts ongoing with other .NET DI projects - time to move on me thinks.

tommed commented Dec 2, 2016

We gave up on Unity have started using structuremap instead which does support dotnet core.
It's a sad day when a library you know, love and use throughout your projects grows cobwebs, but there are other, more active efforts ongoing with other .NET DI projects - time to move on me thinks.

@napalm684

This comment has been minimized.

Show comment
Hide comment
@napalm684

napalm684 Dec 2, 2016

Agree I have had good luck in core with LightInject and it's very unity esque

napalm684 commented Dec 2, 2016

Agree I have had good luck in core with LightInject and it's very unity esque

@ENikS ENikS added the duplicate label Sep 20, 2017

@ENikS ENikS closed this Sep 20, 2017

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