public Func <IServiceProvider, TProxy> CreateProxyFactory <TProxy>(ISolidProxyGenerator proxyGenerator, Func <IServiceProvider, TProxy> implementationFactory) where TProxy : class { var config = new SolidProxyConfig <TProxy>(implementationFactory); return((sp) => { return proxyGenerator.CreateSolidProxy(sp, config.GetProxyConfiguration(sp)).Proxy; }); }
/// <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>(); } }