Files
29WxOrder/Source/MAX.Framework/PrismExtension/Prism.Autofac/AutofacContainerExtension.cs
T
2026-08-31 16:28:23 +08:00

334 lines
9.2 KiB
C#

using Autofac;
using Autofac.Core;
using Autofac.Features.ResolveAnything;
using MAX.Core;
using MAX.Core.Autofac;
using MAX.Core.DependencyInjection;
using MAX.Core.Helpers;
using MAX.Core.Infrastructure;
using MAX.Core.Reflections;
using MAX.Framework.Interfaces;
using MAX.Framework.Prism.Autofac;
using Prism.Ioc;
using Prism.Ioc.Internals;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
namespace Prism.Autofac
{
public class AutofacContainerExtension : IContainerExtension<IContainer>, IContainerInfo
{
private AutofacScopedProvider _currentScope;
public readonly ContainerBuilder Builder;
public IContainer Instance { get; private set; }
public IScopedProvider CurrentScope => _currentScope;
public AutofacContainerExtension()
{
Builder = new ContainerBuilder();
string currentContainer = "CurrentContainer";
Builder.RegisterInstance(this).Named(currentContainer, typeof(AutofacContainerExtension));
Builder.RegisterInstance(this).As<IContainerExtension>();
Builder.RegisterInstance(this).As<IContainerProvider>();
//设置过滤AOP
//IAspectConfiguration configuration = new AspectConfiguration();
//foreach (var item in AppTypeFinder.Assemblies)
//{
// string _namespace = item.FullName;
// if (!Regex.IsMatch(_namespace, "^MAX", RegexOptions.IgnoreCase | RegexOptions.Compiled))
// {
// configuration.NonAspectPredicates.AddNamespace(_namespace);
// }
//}
//Builder.RegisterDynamicProxy(configuration);
}
public AutofacContainerExtension(ContainerBuilder builder)
{
Builder = builder;
string currentContainer = "CurrentContainer";
//Builder.RegisterDynamicProxy();
Builder.RegisterInstance(this).Named(currentContainer, typeof(AutofacContainerExtension));
Builder.RegisterInstance(this).As<IContainerExtension>();
Builder.RegisterInstance(this).As<IContainerProvider>();
}
public IScopedProvider CreateScope()
{
return CreateScopeInternal();
}
protected IScopedProvider CreateScopeInternal()
{
_currentScope = new AutofacScopedProvider(Instance);
return _currentScope;
}
public void FinalizeExtension()
{
if (Instance != null)
{
return;
}
Assembly[] assemblies = AppTypeFinder.Assemblies.ToArray();
// Make sure any not specifically registered concrete type can resolve.
IEnumerable<IStartup> startupList = ReflectionHelper.GetInstancesByInterface<IStartup>(assemblies);
int index = 1;
foreach (IStartup item in startupList.OrderByDescending(a => a.Priority))
{
Debug.WriteLine($"Startup - {index++} : {item.GetType()}");
item.Initialize();
}
// Make sure any not specifically registered concrete type can resolve.
IEnumerable<IDependencyRegistrar> ListDependency = ReflectionHelper.GetInstancesByInterface<IDependencyRegistrar>(assemblies);
foreach (IDependencyRegistrar item in ListDependency)
{
item.Register(Builder);
}
IEnumerable<IPreRegisterTypes> PreRegisterTypes = ReflectionHelper.GetInstancesByInterface<IPreRegisterTypes>(assemblies);
foreach (IPreRegisterTypes item in PreRegisterTypes)
{
item.RegisterTypes(this);
}
Builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
Instance = Builder.Build();
IocManager.SetContainer(Instance);
}
public bool IsRegistered(Type type)
{
return Instance.IsRegistered(type);
}
public bool IsRegistered(Type type, string name)
{
return Instance.IsRegisteredWithName(name, type);
}
public IContainerRegistry Register(Type from, Type to)
{
Builder.RegisterType(to).As(from);
return this;
}
public IContainerRegistry Register(Type from, Type to, string name)
{
Builder.RegisterType(to).Named(name, from);
return this;
}
public IContainerRegistry RegisterInstance(Type type, object instance)
{
Builder.RegisterInstance(instance).As(type);
return this;
}
public IContainerRegistry RegisterInstance(Type type, object instance, string name)
{
Builder.RegisterInstance(instance).Named(name, type);
return this;
}
public IContainerRegistry RegisterSingleton(Type from, Type to)
{
Builder.RegisterType(to).As(from).SingleInstance();
return this;
}
public IContainerRegistry RegisterSingleton(Type from, Type to, string name)
{
Builder.RegisterType(to).Named(name, from).SingleInstance();
return this;
}
public IContainerRegistry RegisterSingleton(Type type, Func<object> factoryMethod)
{
Debugger.Break();
throw new NotImplementedException();
}
public IContainerRegistry RegisterSingleton(Type type, Func<IContainerProvider, object> factoryMethod)
{
Debugger.Break();
throw new NotImplementedException();
}
public object Resolve(Type type)
{
return Instance.Resolve(type);
}
public object Resolve(Type type, params (Type Type, object Instance)[] parameters)
{
List<TypedParameter> listps = new List<TypedParameter>();
foreach ((Type Type, object Instance) item in parameters)
{
TypedParameter ps = new TypedParameter(item.Type, item.Instance);
listps.Add(ps);
}
return Instance.Resolve(type, listps);
}
public object Resolve(Type type, string name)
{
return Instance.ResolveNamed(name, type);
}
public object Resolve(Type type, string name, params (Type Type, object Instance)[] parameters)
{
List<TypedParameter> listps = new List<TypedParameter>();
foreach ((Type Type, object Instance) item in parameters)
{
TypedParameter ps = new TypedParameter(item.Type, item.Instance);
listps.Add(ps);
}
return Instance.ResolveNamed(name, type, listps);
}
public IContainerRegistry Register(Type type, Func<object> factoryMethod)
{
Debugger.Break();
throw new NotImplementedException();
}
public IContainerRegistry Register(Type type, Func<IContainerProvider, object> factoryMethod)
{
Debugger.Break();
throw new NotImplementedException();
}
public IContainerRegistry RegisterMany(Type type, params Type[] serviceTypes)
{
Debugger.Break();
throw new NotImplementedException();
}
public IContainerRegistry RegisterManySingleton(Type type, params Type[] serviceTypes)
{
Debugger.Break();
throw new NotImplementedException();
}
public IContainerRegistry RegisterScoped(Type from, Type to)
{
Debugger.Break();
throw new NotImplementedException();
}
public IContainerRegistry RegisterScoped(Type type, Func<object> factoryMethod)
{
Debugger.Break();
throw new NotImplementedException();
}
public IContainerRegistry RegisterScoped(Type type, Func<IContainerProvider, object> factoryMethod)
{
Debugger.Break();
throw new NotImplementedException();
}
public Type GetRegistrationType(string key)
{
Type retType = null;
//First try friendly name registration. If not found, try type registration
foreach (IComponentRegistration registration in Instance.ComponentRegistry.Registrations)
{
//System.Diagnostics.Debug.WriteLine(registration.ToString());
foreach (Service service in registration.Services)
{
//System.Diagnostics.Debug.WriteLine(service.ToString());
if (service is KeyedService ks)
{
if (key.Equals(ks.ServiceKey.ToString(), StringComparison.Ordinal))
{
if (Instance.ComponentRegistry.TryGetServiceRegistration(service, out ServiceRegistration serviceRegistration))
{
retType = serviceRegistration.Registration.Target.Activator.LimitType;
}
}
}
}
}
//Instance.TryResolveService
//retType = Instance.ResolveNamed<object>(key).GetType();
if (retType == null)
{
retType = Instance.ResolveNamed<object>(key).GetType();
if (retType == null)
{
retType = typeof(System.Object);
}
}
return retType;
}
public Type GetRegistrationType(Type serviceType)
{
Debugger.Break();
throw new NotImplementedException();
}
private class AutofacScopedProvider : IScopedProvider
{
private readonly IContainer _container;
public bool IsAttached { get; set; }
public IScopedProvider CurrentScope => this;
public IScopedProvider CreateScope()
{
return this;
}
public AutofacScopedProvider(IContainer container)
{
_container = container;
}
public void Dispose()
{
_container.Dispose();
}
public object Resolve(Type type)
{
return _container.Resolve(type);
}
public object Resolve(Type type, params (Type Type, object Instance)[] parameters)
{
List<TypedParameter> listps = new List<TypedParameter>();
foreach ((Type Type, object Instance) item in parameters)
{
TypedParameter ps = new TypedParameter(item.Type, item.Instance);
listps.Add(ps);
}
return _container.Resolve(type, listps);
}
public object Resolve(Type type, string name)
{
return _container.ResolveNamed(name, type);
}
public object Resolve(Type type, string name, params (Type Type, object Instance)[] parameters)
{
List<TypedParameter> list = new List<TypedParameter>();
foreach ((Type Type, object Instance) item in parameters)
{
TypedParameter ps = new TypedParameter(item.Type, item.Instance);
list.Add(ps);
}
return _container.ResolveNamed(name, type, list);
}
}
}
}