添加项目文件。

This commit is contained in:
chfei committed 2026-10-26 18:21:42 +08:00
1 parent 54c7b83029
commit ef50fa0620
84 files changed
+9188

No files matched your search

@@ -0,0 +1,243 @@
using System.Linq.Expressions;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using Prism.Properties;
namespace Prism.Commands
{
/// <summary>
/// Provides an implementation of the <see cref="IAsyncCommand"/>
/// </summary>
public class AsyncDelegateCommand : DelegateCommandBase, IAsyncCommand
{
private bool _enableParallelExecution = false;
private bool _isExecuting = false;
private readonly Func<CancellationToken, Task> _executeMethod;
private Func<bool> _canExecuteMethod;
private Func<CancellationToken> _getCancellationToken = () => CancellationToken.None;
/// <summary>
/// Creates a new instance of <see cref="AsyncDelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution.
/// </summary>
/// <param name="executeMethod">The <see cref="Func{Task}"/> to invoke when <see cref="ICommand.Execute(object)"/> is called.</param>
public AsyncDelegateCommand(Func<Task> executeMethod)
#if NET6_0_OR_GREATER
: this (c => executeMethod().WaitAsync(c), () => true)
#else
: this(c => executeMethod(), () => true)
#endif
{
}
/// <summary>
/// Creates a new instance of <see cref="AsyncDelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution.
/// </summary>
/// <param name="executeMethod">The <see cref="Func{CancellationToken, Task}"/> to invoke when <see cref="ICommand.Execute(object)"/> is called.</param>
public AsyncDelegateCommand(Func<CancellationToken, Task> executeMethod)
: this(executeMethod, () => true)
{
}
/// <summary>
/// Creates a new instance of <see cref="DelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution
/// and a <see langword="Func" /> to query for determining if the command can execute.
/// </summary>
/// <param name="executeMethod">The <see cref="Func{Task}"/> to invoke when <see cref="ICommand.Execute"/> is called.</param>
/// <param name="canExecuteMethod">The delegate to invoke when <see cref="ICommand.CanExecute"/> is called</param>
public AsyncDelegateCommand(Func<Task> executeMethod, Func<bool> canExecuteMethod)
#if NET6_0_OR_GREATER
: this(c => executeMethod().WaitAsync(c), canExecuteMethod)
#else
: this(c => executeMethod(), canExecuteMethod)
#endif
{
}
/// <summary>
/// Creates a new instance of <see cref="DelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution
/// and a <see langword="Func" /> to query for determining if the command can execute.
/// </summary>
/// <param name="executeMethod">The <see cref="Func{CancellationToken, Task}"/> to invoke when <see cref="ICommand.Execute"/> is called.</param>
/// <param name="canExecuteMethod">The delegate to invoke when <see cref="ICommand.CanExecute"/> is called</param>
public AsyncDelegateCommand(Func<CancellationToken, Task> executeMethod, Func<bool> canExecuteMethod)
: base()
{
if (executeMethod == null || canExecuteMethod == null)
throw new ArgumentNullException(nameof(executeMethod), "Neither the executeMethod nor the canExecuteMethod delegates can be null");
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
}
/// <summary>
/// Gets the current state of the AsyncDelegateCommand
/// </summary>
public bool IsExecuting
{
get => _isExecuting;
private set
{
_isExecuting = value;
OnCanExecuteChanged();
}
}
///<summary>
/// Executes the command.
///</summary>
public async Task Execute(CancellationToken? cancellationToken = null)
{
var token = cancellationToken ?? _getCancellationToken();
try
{
if (!_enableParallelExecution && IsExecuting)
return;
IsExecuting = true;
await _executeMethod(token)
.ConfigureAwait(false);
}
catch
{
throw;
}
finally
{
IsExecuting = false;
}
}
/// <summary>
/// Determines if the command can be executed.
/// </summary>
/// <returns>Returns <see langword="true"/> if the command can execute,otherwise returns <see langword="false"/>.</returns>
public bool CanExecute()
{
try
{
if (!_enableParallelExecution && IsExecuting)
return false;
return _canExecuteMethod?.Invoke() ?? true;
}
catch (Exception ex)
{
return false;
}
}
/// <summary>
/// Handle the internal invocation of <see cref="ICommand.Execute(object)"/>
/// </summary>
/// <param name="parameter">Command Parameter</param>
protected override async void Execute(object parameter)
{
// We don't want to wrap this in a try/catch because we already handle
// or mean to rethrow the exception in the call with the CancellationToken.
var cancellationToken = _getCancellationToken();
await Execute(cancellationToken)
.ConfigureAwait(false);
}
/// <summary>
/// Handle the internal invocation of <see cref="ICommand.CanExecute(object)"/>
/// </summary>
/// <param name="parameter"></param>
/// <returns><see langword="true"/> if the Command Can Execute, otherwise <see langword="false" /></returns>
protected override bool CanExecute(object parameter)
{
return CanExecute();
}
/// <summary>
/// Enables Parallel Execution of Async Tasks
/// </summary>
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
public AsyncDelegateCommand EnableParallelExecution()
{
_enableParallelExecution = true;
return this;
}
/// <summary>
/// Sets the <see cref="CancellationTokenSourceFactory(Func{CancellationToken})"/> based on the specified timeout.
/// </summary>
/// <param name="timeout">A specified timeout.</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
public AsyncDelegateCommand CancelAfter(TimeSpan timeout) =>
CancellationTokenSourceFactory(() => new CancellationTokenSource(timeout).Token);
/// <summary>
/// Provides a delegate callback to provide a default CancellationToken when the Command is invoked.
/// </summary>
/// <param name="factory">The default <see cref="CancellationToken"/> Factory.</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
public AsyncDelegateCommand CancellationTokenSourceFactory(Func<CancellationToken> factory)
{
_getCancellationToken = factory;
return this;
}
/// <summary>
/// Observes a property that implements INotifyPropertyChanged, and automatically calls DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications.
/// </summary>
/// <typeparam name="T">The object type containing the property specified in the expression.</typeparam>
/// <param name="propertyExpression">The property expression. Example: ObservesProperty(() => PropertyName).</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
public AsyncDelegateCommand ObservesProperty<T>(Expression<Func<T>> propertyExpression)
{
ObservesPropertyInternal(propertyExpression);
return this;
}
/// <summary>
/// Observes a property that is used to determine if this command can execute, and if it implements INotifyPropertyChanged it will automatically call DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications.
/// </summary>
/// <param name="canExecuteExpression">The property expression. Example: ObservesCanExecute(() => PropertyName).</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
public AsyncDelegateCommand ObservesCanExecute(Expression<Func<bool>> canExecuteExpression)
{
_canExecuteMethod = canExecuteExpression.Compile();
ObservesPropertyInternal(canExecuteExpression);
return this;
}
/// <summary>
/// Provides the ability to connect a delegate to catch exceptions encountered by CanExecute or the Execute methods of the DelegateCommand
/// </summary>
/// <param name="catch">TThe callback when a specific exception is encountered</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
public AsyncDelegateCommand Catch<TException>(Action<TException> @catch)
where TException : Exception
{
return this;
}
/// <summary>
/// Provides the ability to connect a delegate to catch exceptions encountered by CanExecute or the Execute methods of the DelegateCommand
/// </summary>
/// <param name="catch">The generic / default callback when an exception is encountered</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand"/>.</returns>
public AsyncDelegateCommand Catch(Action<Exception> @catch)
{
return this;
}
Task IAsyncCommand.ExecuteAsync(object parameter)
{
return Execute(_getCancellationToken());
}
Task IAsyncCommand.ExecuteAsync(object parameter, CancellationToken cancellationToken)
{
return Execute(cancellationToken);
}
}
}
@@ -0,0 +1,284 @@
using System.Linq.Expressions;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Reflection.Emit;
using System.Resources;
namespace Prism.Commands
{
/// <summary>
/// Provides an implementation of the <see cref="IAsyncCommand"/> with a generic parameter type.
/// </summary>
/// <typeparam name="T"></typeparam>
public class AsyncDelegateCommand<T> : DelegateCommandBase, IAsyncCommand
{
private bool _enableParallelExecution = false;
private bool _isExecuting = false;
private readonly Func<T, CancellationToken, Task> _executeMethod;
private Func<T, bool> _canExecuteMethod;
private Func<CancellationToken> _getCancellationToken = () => CancellationToken.None;
/// <summary>
/// Creates a new instance of <see cref="AsyncDelegateCommand{T}"/> with the <see cref="Func{Task}"/> to invoke on execution.
/// </summary>
/// <param name="executeMethod">The <see cref="Func{T, Task}"/> to invoke when <see cref="ICommand.Execute(object)"/> is called.</param>
public AsyncDelegateCommand(Func<T, Task> executeMethod)
#if NET6_0_OR_GREATER
: this((p,t) => executeMethod(p).WaitAsync(t), _ => true)
#else
: this((p, t) => executeMethod(p), _ => true)
#endif
{
}
/// <summary>
/// Creates a new instance of <see cref="AsyncDelegateCommand{T}"/> with the <see cref="Func{Task}"/> to invoke on execution.
/// </summary>
/// <param name="executeMethod">The <see cref="Func{T, CancellationToken, Task}"/> to invoke when <see cref="ICommand.Execute(object)"/> is called.</param>
public AsyncDelegateCommand(Func<T, CancellationToken, Task> executeMethod)
: this(executeMethod, _ => true)
{
}
/// <summary>
/// Creates a new instance of <see cref="DelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution
/// and a <see langword="Func" /> to query for determining if the command can execute.
/// </summary>
/// <param name="executeMethod">The <see cref="Func{T, Task}"/> to invoke when <see cref="ICommand.Execute"/> is called.</param>
/// <param name="canExecuteMethod">The delegate to invoke when <see cref="ICommand.CanExecute"/> is called</param>
public AsyncDelegateCommand(Func<T, Task> executeMethod, Func<T, bool> canExecuteMethod)
#if NET6_0_OR_GREATER
: this((p, c) => executeMethod(p).WaitAsync(c), canExecuteMethod)
#else
: this((p, c) => executeMethod(p), canExecuteMethod)
#endif
{
}
/// <summary>
/// Creates a new instance of <see cref="DelegateCommand"/> with the <see cref="Func{Task}"/> to invoke on execution
/// and a <see langword="Func" /> to query for determining if the command can execute.
/// </summary>
/// <param name="executeMethod">The <see cref="Func{T, CancellationToken, Task}"/> to invoke when <see cref="ICommand.Execute"/> is called.</param>
/// <param name="canExecuteMethod">The delegate to invoke when <see cref="ICommand.CanExecute"/> is called</param>
public AsyncDelegateCommand(Func<T, CancellationToken, Task> executeMethod, Func<T, bool> canExecuteMethod)
: base()
{
if (executeMethod == null || canExecuteMethod == null)
throw new ArgumentNullException(nameof(executeMethod), "Neither the executeMethod nor the canExecuteMethod delegates can be null");
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
}
/// <summary>
/// Gets the current state of the AsyncDelegateCommand
/// </summary>
public bool IsExecuting
{
get => _isExecuting;
private set
{
_isExecuting = value;
OnCanExecuteChanged();
}
}
///<summary>
/// Executes the command.
///</summary>
public async Task Execute(T parameter, CancellationToken? cancellationToken = null)
{
var token = cancellationToken ?? _getCancellationToken();
try
{
if (!_enableParallelExecution && IsExecuting)
return;
IsExecuting = true;
await _executeMethod(parameter, token)
.ConfigureAwait(false);
}
catch (Exception ex)
{
throw;
}
finally
{
IsExecuting = false;
}
}
/// <summary>
/// Determines if the command can be executed.
/// </summary>
/// <returns>Returns <see langword="true"/> if the command can execute,otherwise returns <see langword="false"/>.</returns>
public bool CanExecute(T parameter)
{
try
{
if (!_enableParallelExecution && IsExecuting)
return false;
return _canExecuteMethod?.Invoke(parameter) ?? true;
}
catch (Exception ex)
{
throw;
return false;
}
}
/// <summary>
/// Handle the internal invocation of <see cref="ICommand.Execute(object)"/>
/// </summary>
/// <param name="parameter">Command Parameter</param>
protected override async void Execute(object parameter)
{
var cancellationToken = _getCancellationToken();
T parameterAsT;
try
{
parameterAsT = (T)parameter;
}
catch (Exception ex)
{
throw;
}
// If we had an exception casting the parameter to T ,
// we would have already returned. We want to surface any
// exceptions thrown by the Execute method.
await Execute(parameterAsT, cancellationToken)
.ConfigureAwait(false);
}
/// <summary>
/// Handle the internal invocation of <see cref="ICommand.CanExecute(object)"/>
/// </summary>
/// <param name="parameter"></param>
/// <returns><see langword="true"/> if the Command Can Execute, otherwise <see langword="false" /></returns>
protected override bool CanExecute(object parameter)
{
try
{
return CanExecute((T)parameter);
}
catch (Exception ex)
{
throw;
}
}
/// <summary>
/// Enables Parallel Execution of Async Tasks
/// </summary>
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
public AsyncDelegateCommand<T> EnableParallelExecution()
{
_enableParallelExecution = true;
return this;
}
/// <summary>
/// Sets the <see cref="CancellationTokenSourceFactory(Func{CancellationToken})"/> based on the specified timeout.
/// </summary>
/// <param name="timeout">A specified timeout.</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
public AsyncDelegateCommand<T> CancelAfter(TimeSpan timeout) =>
CancellationTokenSourceFactory(() => new CancellationTokenSource(timeout).Token);
/// <summary>
/// Provides a delegate callback to provide a default CancellationToken when the Command is invoked.
/// </summary>
/// <param name="factory">The default <see cref="CancellationToken"/> Factory.</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
public AsyncDelegateCommand<T> CancellationTokenSourceFactory(Func<CancellationToken> factory)
{
_getCancellationToken = factory;
return this;
}
/// <summary>
/// Observes a property that implements INotifyPropertyChanged, and automatically calls DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications.
/// </summary>
/// <typeparam name="TType">The type of the return value of the method that this delegate encapsulates</typeparam>
/// <param name="propertyExpression">The property expression. Example: ObservesProperty(() => PropertyName).</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
public AsyncDelegateCommand<T> ObservesProperty<TType>(Expression<Func<TType>> propertyExpression)
{
ObservesPropertyInternal(propertyExpression);
return this;
}
/// <summary>
/// Observes a property that is used to determine if this command can execute, and if it implements INotifyPropertyChanged it will automatically call DelegateCommandBase.RaiseCanExecuteChanged on property changed notifications.
/// </summary>
/// <param name="canExecuteExpression">The property expression. Example: ObservesCanExecute(() => PropertyName).</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
public AsyncDelegateCommand<T> ObservesCanExecute(Expression<Func<bool>> canExecuteExpression)
{
Expression<Func<T, bool>> expression = Expression.Lambda<Func<T, bool>>(canExecuteExpression.Body, Expression.Parameter(typeof(T), "o"));
_canExecuteMethod = expression.Compile();
ObservesPropertyInternal(canExecuteExpression);
return this;
}
/// <summary>
/// Provides the ability to connect a delegate to catch exceptions encountered by CanExecute or the Execute methods of the DelegateCommand
/// </summary>
/// <param name="catch">TThe callback when a specific exception is encountered</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
public AsyncDelegateCommand<T> Catch<TException>(Action<TException> @catch)
where TException : Exception
{
return this;
}
/// <summary>
/// Provides the ability to connect a delegate to catch exceptions encountered by CanExecute or the Execute methods of the DelegateCommand
/// </summary>
/// <param name="catch">The generic / default callback when an exception is encountered</param>
/// <returns>The current instance of <see cref="AsyncDelegateCommand{T}"/>.</returns>
public AsyncDelegateCommand<T> Catch(Action<Exception> @catch)
{
return this;
}
async Task IAsyncCommand.ExecuteAsync(object parameter)
{
try
{
// If T is not nullable this may throw an exception
await Execute((T)parameter, _getCancellationToken());
}
catch (Exception ex)
{
throw;
}
}
async Task IAsyncCommand.ExecuteAsync(object parameter, CancellationToken cancellationToken)
{
try
{
// If T is not nullable this may throw an exception
await Execute((T)parameter, cancellationToken);
}
catch (Exception ex)
{
throw;
}
}
}
}
@@ -0,0 +1,28 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Prism.Commands
{
/// <summary>
/// Provides an abstraction layer for custom controls which want to make use of Async Commands
/// </summary>
public interface IAsyncCommand : ICommand
{
/// <summary>
/// Executes the Command with a specified parameter and the Default <see cref="CancellationToken"/>.
/// </summary>
/// <param name="parameter">The Command Parameter</param>
/// <returns>An Asynchronous Task</returns>
Task ExecuteAsync(object parameter);
/// <summary>
/// Executes the Command with a specified parameter and using a <see cref="CancellationToken"/>
/// </summary>
/// <param name="parameter">The Command Parameter</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <returns>An Asynchronous Task</returns>
Task ExecuteAsync(object parameter, CancellationToken cancellationToken);
}
}
@@ -0,0 +1,323 @@
using Autofac;
using Autofac.Core;
using Autofac.Features.ResolveAnything;
using MAX.Core;
using MAX.Core.Autofac;
using MAX.Core.Helpers;
using MAX.Core.Reflections;
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();
IocManager.SetContainerBuilder(Builder);
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;
IocManager.SetContainerBuilder(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)
{
throw new NotImplementedException();
}
public IContainerRegistry RegisterSingleton(Type type, Func<IContainerProvider, object> factoryMethod)
{
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 = [];
foreach ((Type Type, object Instance) item in parameters)
{
TypedParameter ps = new(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 = [];
foreach ((Type Type, object Instance) item in parameters)
{
TypedParameter ps = new(item.Type, item.Instance);
listps.Add(ps);
}
return Instance.ResolveNamed(name, type, listps);
}
public IContainerRegistry Register(Type type, Func<object> factoryMethod)
{
throw new NotImplementedException();
}
public IContainerRegistry Register(Type type, Func<IContainerProvider, object> factoryMethod)
{
throw new NotImplementedException();
}
public IContainerRegistry RegisterMany(Type type, params Type[] serviceTypes)
{
throw new NotImplementedException();
}
public IContainerRegistry RegisterManySingleton(Type type, params Type[] serviceTypes)
{
throw new NotImplementedException();
}
public IContainerRegistry RegisterScoped(Type from, Type to)
{
throw new NotImplementedException();
}
public IContainerRegistry RegisterScoped(Type type, Func<object> factoryMethod)
{
throw new NotImplementedException();
}
public IContainerRegistry RegisterScoped(Type type, Func<IContainerProvider, object> factoryMethod)
{
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)
{
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 = [];
foreach ((Type Type, object Instance) item in parameters)
{
TypedParameter ps = new(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 = [];
foreach ((Type Type, object Instance) item in parameters)
{
TypedParameter ps = new(item.Type, item.Instance);
list.Add(ps);
}
return _container.ResolveNamed(name, type, list);
}
}
}
@@ -0,0 +1,15 @@
using Autofac;
using Prism.Ioc;
namespace Prism.Autofac;
/// <summary>
/// Provides customization extensions for Autofac Applications
/// </summary>
public interface IAutofacContainerExtension : IContainerExtension<IContainer>
{
/// <summary>
/// Gets the <see cref="ContainerBuilder"/> used to register the services for the application
/// </summary>
ContainerBuilder Builder { get; }
}
@@ -0,0 +1,8 @@
using Prism.Ioc;
namespace MAX.Framework.Prism.Autofac;
public interface IPreRegisterTypes
{
void RegisterTypes(IContainerRegistry containerRegistry);
}
@@ -0,0 +1,32 @@
using Prism.Ioc;
using System;
using AutofacCore = Autofac.Core;
namespace Prism.Autofac;
/// <summary>
/// Base application class that uses <see cref="UnityContainerExtension"/> as it's container.
/// </summary>
public abstract class PrismApplication : PrismApplicationBase
{
/// <summary>
/// Create a new <see cref="UnityContainerExtension"/> used by Prism.
/// </summary>
/// <returns>A new <see cref="UnityContainerExtension"/>.</returns>
protected override IContainerExtension CreateContainerExtension()
{
return new AutofacContainerExtension();
}
/// <summary>
/// Registers the <see cref="Type"/>s of the Exceptions that are not considered
/// root exceptions by the <see cref="ExceptionExtensions"/>.
/// </summary>
protected override void RegisterFrameworkExceptionTypes()
{
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(AutofacCore.DependencyResolutionException));
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(AutofacCore.Registration.ComponentNotRegisteredException));
}
}
@@ -0,0 +1,30 @@
using Prism.Ioc;
using System;
using AutofacCore = Autofac.Core;
namespace Prism.Autofac;
/// <summary>
/// Base bootstrapper class that uses <see cref="UnityContainerExtension"/> as it's container.
/// </summary>
public abstract class PrismBootstrapper : PrismBootstrapperBase
{
/// <summary>
/// Create a new <see cref="UnityContainerExtension"/> used by Prism.
/// </summary>
/// <returns>A new <see cref="UnityContainerExtension"/>.</returns>
protected override IContainerExtension CreateContainerExtension()
{
return new AutofacContainerExtension();
}
/// <summary>
/// Registers the <see cref="Type"/>s of the Exceptions that are not considered
/// root exceptions by the <see cref="ExceptionExtensions"/>.
/// </summary>
protected override void RegisterFrameworkExceptionTypes()
{
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(AutofacCore.DependencyResolutionException));
ExceptionExtensions.RegisterFrameworkExceptionType(typeof(AutofacCore.Registration.ComponentNotRegisteredException));
}
}
@@ -0,0 +1,39 @@
using Autofac;
using Prism.Ioc;
namespace Prism.Autofac;
/// <summary>
/// Extensions help get the underlying <see cref="IUnityContainer" />
/// </summary>
public static class PrismIocExtensions
{
/// <summary>
/// Gets the <see cref="IUnityContainer" /> from the <see cref="IContainerProvider" />
/// </summary>
/// <param name="containerProvider">The current <see cref="IContainerProvider" /></param>
/// <returns>The underlying <see cref="IUnityContainer" /></returns>
public static IContainer GetContainer(this IContainerProvider containerProvider)
{
return ((IContainerExtension<IContainer>)containerProvider).Instance;
}
/// <summary>
/// Gets the <see cref="IUnityContainer" /> from the <see cref="IContainerProvider" />
/// </summary>
/// <param name="containerRegistry">The current <see cref="IContainerRegistry" /></param>
/// <returns>The underlying <see cref="IUnityContainer" /></returns>
public static IContainer GetContainer(this IContainerRegistry containerRegistry)
{
return ((IContainerExtension<IContainer>)containerRegistry).Instance;
}
/// <summary>
/// Gets the <see cref="ContainerBuilder"/> used to register services.
/// </summary>
/// <param name="registry"></param>
/// <returns>The current <see cref="ContainerBuilder"/></returns>
public static ContainerBuilder GetBuilder(this IContainerRegistry registry)
{
return ((IAutofacContainerExtension)registry).Builder;
}
}