예제 #1
0
        /// <summary>
        /// Configures a proxy
        /// </summary>
        /// <typeparam name="TProxy"></typeparam>
        /// <param name="serviceProvider"></param>
        /// <param name="interfaceConfig"></param>
        public static void ConfigureProxyInternal <TProxy>(SolidProxyServiceProvider serviceProvider, ISolidInterfaceConfigurationBuilder <TProxy> interfaceConfig) where TProxy : class
        {
            if (serviceProvider.Registrations.Any(o => o.ServiceType != typeof(TProxy)))
            {
                serviceProvider.AddScoped <TProxy, TProxy>();
            }

            var registrationImpls = serviceProvider.Registrations
                                    .Where(o => o.ServiceType == typeof(TProxy))
                                    .SelectMany(o => o.Implementations).ToList();

            foreach (var registration in registrationImpls)
            {
                // check if this registration is mapped to the solid proxy.
                var implementationFactoryTarget = registration.Resolver?.Target;
                if (implementationFactoryTarget == s_proxyFactoryFactory)
                {
                    continue;
                }

                var registrationGuid = Guid.NewGuid();

                var proxyGenerator = serviceProvider.GetRequiredService <ISolidProxyGenerator>();
                Func <IServiceProvider, TProxy> implementationFactory = null;
                //
                // add the configuration for the proxy and register
                // proxy and interface the same way as the removed service.
                //
                switch (registration.RegistrationScope)
                {
                case SolidProxyServiceRegistrationScope.Scoped:
                    serviceProvider.AddScoped(s_proxyFactoryFactory.CreateProxyFactory(proxyGenerator, implementationFactory));
                    break;

                case SolidProxyServiceRegistrationScope.Transient:
                    serviceProvider.AddTransient(s_proxyFactoryFactory.CreateProxyFactory(proxyGenerator, implementationFactory));
                    break;

                case SolidProxyServiceRegistrationScope.Singleton:
                    serviceProvider.AddSingleton(s_proxyFactoryFactory.CreateProxyFactory(proxyGenerator, implementationFactory));
                    break;
                }

                //
                // make sure that all the methods are configured
                //
                if (typeof(TProxy) != typeof(ISolidProxyInvocationImplAdviceConfig))
                {
                    typeof(TProxy).GetMethods().ToList().ForEach(m =>
                    {
                        var methodConfig = interfaceConfig.ConfigureMethod(m);
                        methodConfig.ConfigureAdvice <ISolidProxyInvocationImplAdviceConfig>();
                        methodConfig.AddAdvice(typeof(SolidProxyInvocationImplAdvice <, ,>));
                    });
                }
            }
            ;
        }
        /// <summary>
        /// Resolves the actual instance of the service.
        /// </summary>
        /// <param name="solidProxyServiceProvider"></param>
        /// <returns></returns>
        public new T Resolve(SolidProxyServiceProvider solidProxyServiceProvider)
        {
            var impl = Implementations.LastOrDefault();

            if (impl == null)
            {
                return(default(T));
            }
            return(impl.Resolve(solidProxyServiceProvider));
        }
예제 #3
0
        /// <summary>
        /// Resolves all the registrations
        /// </summary>
        /// <param name="solidProxyServiceProvider"></param>
        /// <returns></returns>
        public IEnumerable ResolveAll(SolidProxyServiceProvider solidProxyServiceProvider)
        {
            var objArr = Implementations
                         .Where(o => o.RegistrationScope != SolidProxyServiceRegistrationScope.Nonexisting)
                         .OrderBy(o => o.RegistrationIdx)
                         .Select(o => o.Resolve(solidProxyServiceProvider))
                         .ToArray();

            var arr = Array.CreateInstance(ServiceType, objArr.Length);

            objArr.CopyTo(arr, 0);
            return(arr);
        }
        /// <summary>
        /// Constructs a new IoC container. The parent provider may be null.
        /// </summary>
        /// <param name="parentServiceProvider"></param>
        public SolidProxyServiceProvider(SolidProxyServiceProvider parentServiceProvider = null)
        {
            _parentServiceProvider = parentServiceProvider;
            _registrations         = new ConcurrentDictionary <Type, SolidProxyServiceRegistration>();
            _disposeChain          = new List <IDisposable>();
            _containerId           = RuntimeHelpers.GetHashCode(this).ToString();

            AddRegistration <IServiceProvider>(
                NewRegistrationIdx(),
                SolidProxyServiceRegistrationScope.Scoped,
                typeof(SolidProxyServiceProvider),
                (sp) => this);
            AddRegistration <SolidProxyServiceProvider>(
                NewRegistrationIdx(),
                SolidProxyServiceRegistrationScope.Scoped,
                typeof(SolidProxyServiceProvider),
                (sp) => this);
        }
예제 #5
0
 /// <summary>
 /// Resolves the object
 /// </summary>
 /// <param name="topServiceProvider"></param>
 /// <returns></returns>
 public new T Resolve(SolidProxyServiceProvider topServiceProvider)
 {
     if (!IsResolved)
     {
         lock (this)
         {
             if (!IsResolved)
             {
                 if (RegistrationScope == SolidProxyServiceRegistrationScope.Singleton)
                 {
                     topServiceProvider = ServiceRegistration.ServiceProvider;
                 }
                 //Console.WriteLine($"Registration for {registration.ServiceType.FullName} not resolved. Resolving {registration.RegistrationScope}@{registration.ServiceProvider.ContainerId} from {topServiceProvider.ContainerId}");
                 _resolved  = Resolver(topServiceProvider);
                 IsResolved = RegistrationScope != SolidProxyServiceRegistrationScope.Transient;
                 if (_resolved is IDisposable disposable)
                 {
                     topServiceProvider._disposeChain.Add(disposable);
                 }
             }
         }
     }
     return(_resolved);
 }
예제 #6
0
        /// <summary>
        /// Creates a resolver based on the implementation type.
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <returns></returns>
        private Func <SolidProxyServiceProvider, T> CreateTypedResolver(SolidProxyServiceProvider serviceProvider)
        {
            if (ImplementationType.IsGenericTypeDefinition)
            {
                return((sp) => throw new Exception("Cannot create instances of generic type definitions."));
            }
            if (ImplementationType.IsInterface)
            {
                return((sp) => default(T));
                //return (sp) => throw new Exception("Cannot create instances of interface types.");
            }
            var ctr = ImplementationType.GetConstructors()
                      .OrderByDescending(o => o.GetParameters().Length)
                      .Where(o => o.GetParameters().All(p => serviceProvider.CanResolve(p.ParameterType)))
                      .FirstOrDefault();

            if (ctr == null)
            {
                var paramTypes = ImplementationType.GetConstructors().SelectMany(o => o.GetParameters()).Select(o => o.ParameterType).Distinct()
                                 .Select(o => $"{o.FullName}:{serviceProvider.CanResolve(o)}").ToList();
                throw new Exception($"Cannot instantiate {ImplementationType.FullName}:{string.Join(",", paramTypes)}");
            }
            var argTypes = ctr.GetParameters().Select(o => o.ParameterType).ToArray();

            return((sp) =>
            {
                var args = argTypes.Select(o => serviceProvider.GetService(o)).ToArray();
                if (args.Any(o => o == null))
                {
                    throw new Exception($"Cannot instantiate {ImplementationType.FullName}");
                }
                var impl = Activator.CreateInstance(ImplementationType, args);

                return (T)impl;
            });
        }
 /// <summary>
 /// Resolves a specific type
 /// </summary>
 /// <param name="solidProxyServiceProvider"></param>
 /// <returns></returns>
 protected override object ResolveTyped(SolidProxyServiceProvider solidProxyServiceProvider)
 {
     throw new NotImplementedException("Cannot resolve generic types");
 }
 /// <summary>
 /// Creates a resolver
 /// </summary>
 /// <param name="serviceProvider"></param>
 /// <returns></returns>
 protected override Delegate CreateResolver(SolidProxyServiceProvider serviceProvider)
 {
     throw new NotImplementedException("Cannot resolve generic types");
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="serviceProvider"></param>
 /// <param name="serviceType"></param>
 public SolidProxyServiceRegistrationGeneric(SolidProxyServiceProvider serviceProvider, Type serviceType) : base(serviceProvider)
 {
     ServiceType = serviceType;
 }
예제 #10
0
 /// <summary>
 /// Creates the resolver
 /// </summary>
 /// <param name="serviceProvider"></param>
 /// <returns></returns>
 protected override Delegate CreateResolver(SolidProxyServiceProvider serviceProvider)
 {
     return(CreateTypedResolver(serviceProvider));
 }
예제 #11
0
 /// <summary>
 /// Resolves the typed instance
 /// </summary>
 /// <param name="solidProxyServiceProvider"></param>
 /// <returns></returns>
 protected override object ResolveTyped(SolidProxyServiceProvider solidProxyServiceProvider)
 {
     return(Resolve(solidProxyServiceProvider));
 }
예제 #12
0
 /// <summary>
 /// Resolves the typed object
 /// </summary>
 /// <param name="solidProxyServiceProvider"></param>
 /// <returns></returns>
 protected abstract object ResolveTyped(SolidProxyServiceProvider solidProxyServiceProvider);
예제 #13
0
 /// <summary>
 /// Resolves the object
 /// </summary>
 /// <param name="solidProxyServiceProvider"></param>
 /// <returns></returns>
 public object Resolve(SolidProxyServiceProvider solidProxyServiceProvider)
 {
     return(ResolveTyped(solidProxyServiceProvider));
 }
예제 #14
0
 /// <summary>
 /// Constructs the resolver
 /// </summary>
 /// <param name="serviceProvider"></param>
 /// <returns></returns>
 protected abstract Delegate CreateResolver(SolidProxyServiceProvider serviceProvider);
예제 #15
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="serviceProvider"></param>
 protected SolidProxyServiceRegistration(SolidProxyServiceProvider serviceProvider)
 {
     ServiceProvider  = serviceProvider;
     _implementations = new List <SolidProxyServiceRegistrationImplementation>();
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="serviceProvider"></param>
 public SolidProxyServiceRegistration(SolidProxyServiceProvider serviceProvider) : base(serviceProvider)
 {
 }