-
-
Notifications
You must be signed in to change notification settings - Fork 175
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
请问Autofac如何接入 #30
Comments
@christan-duplicate
设置 |
请问有具体的例子吗? |
@christan-duplicate [Controller(SingleInstance = false)] 表示每次请求都重新创建控制器 |
如果不设为 [Controller(SingleInstance = false)] |
@christan-duplicate |
写了个,没加 SingIeInstance = false,暂时没发现问题: apiServer.ActionFactory.ControllerInstance += (o, e) =>
{
var type = e.Type;
var constructors = type.GetConstructors();
var parameters = constructors.Max(c => c.GetParameters());
if (parameters.Length <= 0) return;
var args = new object[parameters.Length];
for (var i = 0; i < parameters.Length; i++)
{
if (AutofacContainer.Container.IsRegistered(parameters[i].ParameterType))
{
args[i] = AutofacContainer.Resolve(parameters[i].ParameterType);
}
else
{
args[i] = parameters[i].ParameterType.IsValueType ? Activator.CreateInstance(parameters[i].ParameterType) : null;
}
}
e.Controller = Activator.CreateInstance(type, args);
}; |
AutofacContainer 能否提供下源码 |
1、AutofacContainer.cs /// <summary>
/// Autofac容器
/// </summary>
public class AutofacContainer
{
public static IContainer Container { get; private set; }
public static void Set(IContainer c)
{
Container = c;
}
public static T Resolve<T>()
{
if (Container == null) throw new ArgumentNullException(nameof(Container));
return Container.Resolve<T>();
}
public static object Resolve(Type serviceType)
{
if (Container == null) throw new ArgumentNullException(nameof(Container));
return Container.Resolve(serviceType);
}
} 2、GenericHostAutofacServiceProviderFactory.cs internal class GenericHostAutofacServiceProviderFactory : IServiceProviderFactory<ContainerBuilder>
{
private readonly AutofacServiceProviderFactory _default;
public GenericHostAutofacServiceProviderFactory(Action<ContainerBuilder> configure = null)
{
_default = new AutofacServiceProviderFactory(configure);
}
public ContainerBuilder CreateBuilder(IServiceCollection services)
{
var host = services.Last(sd => sd.ServiceType == typeof(IHost) && sd.ImplementationType != null);
services.Remove(host);
var newSd = new ServiceDescriptor(host.ImplementationType, host.ImplementationType, host.Lifetime);
services.Add(newSd);
var builder = _default.CreateBuilder(services);
builder.Register(ctx => new HostDecorator((IHost)ctx.Resolve(host.ImplementationType),
ctx.Resolve<ILifetimeScope>(), ctx.Resolve<ILogger<Container>>()))
.As<IHost>().ExternallyOwned();
return builder;
}
public IServiceProvider CreateServiceProvider(ContainerBuilder containerBuilder)
{
return _default.CreateServiceProvider(containerBuilder);
}
private class HostDecorator : IHost
{
private readonly IHost _host;
private ILifetimeScope _scope;
private readonly ILogger<Container> _logger;
public HostDecorator(IHost host, ILifetimeScope scope, ILogger<Container> logger)
{
_host = host;
_scope = scope;
_logger = logger;
}
public void Dispose()
{
var scope = Interlocked.CompareExchange(ref _scope, null, null);
if (scope != null)
{
scope = Interlocked.CompareExchange(ref _scope, null, scope);
if (scope != null)
{
scope.Dispose();
_logger.LogInformation("Autofac container disposed");
}
}
}
public Task StartAsync(CancellationToken cancellationToken = new CancellationToken())
=> _host.StartAsync(cancellationToken);
public Task StopAsync(CancellationToken cancellationToken = new CancellationToken())
=> _host.StopAsync(cancellationToken);
public IServiceProvider Services => _host.Services;
}
} 3、AutofacHostBuilderExtensions.cs public static class AutofacHostBuilderExtensions
{
public static IHostBuilder UseAutofac(this IHostBuilder builder, Action<ContainerBuilder> configure = null)
{
builder.UseServiceProviderFactory(new GenericHostAutofacServiceProviderFactory(configure));
builder.ConfigureContainer<ContainerBuilder>((_, cb) => cb.RegisterBuildCallback(AutofacContainer.Set));
return builder;
}
public static IHostBuilder ConfigureAutofac(this IHostBuilder builder, Action<HostBuilderContext, ContainerBuilder> configure) => builder.ConfigureContainer(configure);
public static IHostBuilder ConfigureAutofac(this IHostBuilder builder, Action<ContainerBuilder> configure) => builder.ConfigureAutofac((_, cb) => configure(cb));
public static IHostBuilder AddAutofacModule<T>(this IHostBuilder builder) where T : IModule => builder.ConfigureAutofac((ctx, cb) =>
{
var constructors = typeof(T).GetConstructors();
var knownTypes = new Dictionary<Type, object>
{
[typeof(IConfiguration)] = ctx.Configuration,
[typeof(IHostingEnvironment)] = ctx.HostingEnvironment,
[typeof(HostBuilderContext)] = ctx
};
var cnt = -1;
ConstructorInfo constructor = null;
ParameterInfo[] constrParams = null;
foreach (var item in constructors)
{
var parameters = item.GetParameters();
if (parameters.Length <= cnt) continue;
if (!parameters.All(info => knownTypes.ContainsKey(info.ParameterType))) continue;
cnt = parameters.Length;
constructor = item;
constrParams = parameters;
}
if (constructor == null)
throw new DependencyResolutionException(
$"Cannot find compatible constructor for module {typeof(T)}, can have parametrized constructor with {nameof(IConfiguration)}, {nameof(IHostingEnvironment)} or/and {nameof(HostBuilderContext)} parameters");
var args = constrParams.Select(p => knownTypes[p.ParameterType]).ToArray();
var module = (IModule) constructor.Invoke(args);
cb.RegisterModule(module);
});
public static IHostBuilder AddAutofacModule(this IHostBuilder builder, IModule module) => builder.ConfigureAutofac(cb => cb.RegisterModule(module));
public static IHostBuilder AddAutofacModule(this IHostBuilder builder, Func<HostBuilderContext, IModule> factory) => builder.ConfigureAutofac((ctx, cb) => cb.RegisterModule(factory(ctx)));
} 4、AutofacAutoRegisterAttribute.cs /// <inheritdoc />
/// <summary>
/// AutoFac 自动注入属性
/// </summary>
public class AutofacAutoRegisterAttribute : Attribute
{
} 5、Consoles.cs class Program
{
static void Main(string[] args)
{
var builder = new HostBuilder()
.UseAutofac((cb) =>
{
var assemblies = new[]
{
//这里加上你自己的
Assembly.Load("My.Domain"),
Assembly.Load("My.Service"),
Assembly.Load("My.Api.Server.Controllers"),
Assembly.Load("My.Api.Server")
};
//AutofacAutoRegisterAttribute,这个是我自己写的空Attribute,只有标志这个的才使用
cb.RegisterAssemblyTypes(assemblies)
.Where(t => t.GetCustomAttribute<AutofacAutoRegisterAttribute>() != null)
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
})
.ConfigureServices((hostContext, services) =>
{
//这个就是FastHttpApi的HttpServerHosted了。。。
services.AddHostedService<HttpServerHosted>();
});
builder.Build().Run();
}
} |
3Q |
cb.Register(x =>
我的数据库连接池没有释放。等程序关闭的时候 才 Console.WriteLine("释放资源"+x.ToString()); 连接池也满了。大神求指导 |
|
请问Autofac如何接入
The text was updated successfully, but these errors were encountered: