private ISolidProxyConfiguration CreateProxyConfiguration(ISolidInterfaceConfigurationBuilder cb) { var ct = typeof(ISolidProxyConfiguration <>).MakeGenericType(cb.InterfaceType); var ic = ServiceProvider.GetService(ct); return((ISolidProxyConfiguration)ic); }
/// <summary> /// Configures the proxy /// </summary> /// <typeparam name="TProxy"></typeparam> /// <param name="interfaceConfig"></param> public virtual void ConfigureProxy <TProxy>(ISolidInterfaceConfigurationBuilder <TProxy> interfaceConfig) where TProxy : class { if (ParentScope == null) { throw new Exception($"{GetType().FullName} does not implement ConfigureProxy"); } ((SolidConfigurationScope)ParentScope).ConfigureProxy(interfaceConfig); }
/// <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>(); } }
/// <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> /// Configures a proxy /// </summary> /// <typeparam name="TProxy"></typeparam> /// <param name="interfaceConfig"></param> public override void ConfigureProxy <TProxy>(ISolidInterfaceConfigurationBuilder <TProxy> interfaceConfig) { ConfigureProxyInternal(ServiceProvider, interfaceConfig); }
/// <summary> /// Configures the proxy /// </summary> /// <typeparam name="TProxy"></typeparam> /// <param name="interfaceConfig"></param> public override void ConfigureProxy <TProxy>(ISolidInterfaceConfigurationBuilder <TProxy> interfaceConfig) { DoIfMissing <ISolidProxy <TProxy> >(() => { // get the service definition and remove it(added later) var registrations = UnityContainer.Registrations.Where(o => o.RegisteredType == typeof(TProxy)); foreach (var registration in registrations) { } //if (registration.MappedToType == typeof(SolidProxy<TProxy>)) //{ // throw new Exception("Proxy already configured"); //} //registration //UnityContainer.REg // // create implementation factory function. // Func <IServiceProvider, object> implementationFactory = null; //if (service.ImplementationFactory != null) //{ // implementationFactory = sp => service.ImplementationFactory.Invoke(sp); //} //else if (service.ImplementationInstance != null) //{ // implementationFactory = sp => 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 => sp.GetRequiredService(service.ImplementationType); // } //} //else //{ // throw new Exception("Cannot determine implementation type"); //} //// //// add the configuration for the proxy and register //// proxy and interface the same way as the removed service. //// //ServiceCollection.AddSingleton(o => o.GetRequiredService<ISolidProxyConfigurationStore>().GetProxyConfiguration<TProxy>()); //switch (service.Lifetime) //{ // case ServiceLifetime.Scoped: // ServiceCollection.AddScoped<SolidProxy<TProxy>, SolidProxy<TProxy>>(); // ServiceCollection.AddScoped(o => o.GetRequiredService<SolidProxy<TProxy>>().Proxy); // break; // case ServiceLifetime.Transient: // ServiceCollection.AddTransient<SolidProxy<TProxy>, SolidProxy<TProxy>>(); // ServiceCollection.AddTransient(o => o.GetRequiredService<SolidProxy<TProxy>>().Proxy); // break; // case ServiceLifetime.Singleton: // ServiceCollection.AddSingleton<SolidProxy<TProxy>, SolidProxy<TProxy>>(); // ServiceCollection.AddSingleton(o => o.GetRequiredService<SolidProxy<TProxy>>().Proxy); // break; //} // // make sure that all the methods are configured // interfaceConfig.Methods.ToList().ForEach(methodConfig => { // // configure implementation advice if implementation exists. // if (implementationFactory != null) { var invocAdviceConfig = methodConfig.ConfigureAdvice <ISolidProxyInvocationImplAdviceConfig>(); invocAdviceConfig.Enabled = true; invocAdviceConfig.ImplementationFactory = implementationFactory; methodConfig.AddAdvice(typeof(SolidProxyInvocationImplAdvice <, ,>)); } }); }); }
/// <summary> /// Constructs a new instance /// </summary> /// <param name="parentScope"></param> /// <param name="solidProxyConfigurationStore"></param> public SolidProxyConfiguration(ISolidInterfaceConfigurationBuilder <TInterface> parentScope, ISolidProxyConfigurationStore solidProxyConfigurationStore) : base(SolidScopeType.Interface, parentScope) { SolidProxyConfigurationStore = solidProxyConfigurationStore; _invocationConfigurations = new ConcurrentDictionary <MethodInfo, ISolidProxyInvocationConfiguration>(); }