示例#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 <, ,>));
                    });
                }
            }
            ;
        }
示例#2
0
        /// <summary>
        /// Configures the proxy
        /// </summary>
        /// <typeparam name="TProxy"></typeparam>
        /// <param name="interfaceConfig"></param>
        public override void ConfigureProxy <TProxy>(ISolidInterfaceConfigurationBuilder <TProxy> interfaceConfig)
        {
            var services = ServiceCollection.Where(o => o.ServiceType == typeof(TProxy)).ToList();

            foreach (var service in services)
            {
                //
                // check if this service has been configured already.
                //
                var implementationFactoryTarget = service.ImplementationFactory?.Target?.GetType()?.DeclaringType;
                if (implementationFactoryTarget == GetType())
                {
                    continue;
                }

                // remove the service difinition - added again later
                ServiceCollection.Remove(service);

                //
                // create implementation factory function.
                //
                Func <IServiceProvider, TProxy> implementationFactory = null;
                if (service.ImplementationFactory != null)
                {
                    implementationFactory = sp => (TProxy)service.ImplementationFactory.Invoke(sp);
                }
                else if (service.ImplementationInstance != null)
                {
                    implementationFactory = sp => (TProxy)service.ImplementationInstance;
                }
                else if (service.ImplementationType != null)
                {
                    if (service.ImplementationType.IsClass)
                    {
                        DoIfMissing(service.ImplementationType, () => ServiceCollection.Add(new ServiceDescriptor(service.ImplementationType, service.ImplementationType, service.Lifetime)));
                        implementationFactory = sp => (TProxy)sp.GetRequiredService(service.ImplementationType);
                    }
                    else
                    {
                        implementationFactory = null;
                    }
                }
                else
                {
                    throw new Exception("Cannot determine implementation type");
                }

                Func <IServiceProvider, ISolidProxied <TProxy> > proxiedFactory = (sp) => new SolidProxied <TProxy>(implementationFactory(sp));

                //
                // add the configuration for the proxy and register
                // proxy and interface the same way as the removed service.
                //
                var proxyGenerator = SolidProxyGenerator;
                var config         = new SolidProxyConfig <TProxy>(implementationFactory);
                ServiceCollection.AddSingleton(config.GetProxyConfiguration);

                Func <IServiceProvider, TProxy> proxyFactory = (sp) =>
                {
                    return(proxyGenerator.CreateSolidProxy(sp, config.GetProxyConfiguration(sp)).Proxy);
                };
                switch (service.Lifetime)
                {
                case ServiceLifetime.Scoped:
                    ServiceCollection.AddScoped(proxyFactory);
                    ServiceCollection.AddScoped(proxiedFactory);
                    break;

                case ServiceLifetime.Transient:
                    ServiceCollection.AddTransient(proxyFactory);
                    ServiceCollection.AddTransient(proxiedFactory);
                    break;

                case ServiceLifetime.Singleton:
                    ServiceCollection.AddSingleton(proxyFactory);
                    ServiceCollection.AddSingleton(proxiedFactory);
                    break;
                }
            }
            ;

            //
            // make sure that all the methods are configured
            //
            var proxyMethods = GetProxyMethods <TProxy>();

            foreach (var m in proxyMethods)
            {
                var methodConfig = interfaceConfig.ConfigureMethod(m);
                methodConfig.ConfigureAdvice <ISolidProxyInvocationImplAdviceConfig>();
            }
        }