添加项目文件。
This commit is contained in:
1 parent
54c7b83029
commit
ef50fa0620
84 files changed
+9188
No files matched your search
@@ -0,0 +1,34 @@
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Framework.Commons;
|
||||
|
||||
public struct KeyValue
|
||||
{
|
||||
public KeyValue(string key, string value)
|
||||
{
|
||||
Key = key;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Key { get; set; }
|
||||
public string Value { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new();
|
||||
stringBuilder.Append('[');
|
||||
if (Key != null)
|
||||
{
|
||||
stringBuilder.Append(Key.ToString());
|
||||
}
|
||||
|
||||
stringBuilder.Append(", ");
|
||||
if (Value != null)
|
||||
{
|
||||
stringBuilder.Append(Value.ToString());
|
||||
}
|
||||
|
||||
stringBuilder.Append(']');
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace MAX.Framework.Controls.Attach;
|
||||
|
||||
/// <summary>
|
||||
/// 弹出窗口属性值
|
||||
/// </summary>
|
||||
public class DialogWindowProperty
|
||||
{
|
||||
public static readonly DependencyProperty WindowStartupLocationProperty = DependencyProperty.RegisterAttached(
|
||||
"WindowStartupLocation", typeof(WindowStartupLocation), typeof(DialogWindowProperty), new PropertyMetadata(WindowStartupLocation.CenterScreen));
|
||||
public static void SetWindowStartupLocation(DependencyObject element, WindowStartupLocation value)
|
||||
=> element.SetValue(WindowStartupLocationProperty, value);
|
||||
public static WindowStartupLocation GetWindowStartupLocation(DependencyObject element)
|
||||
=> (WindowStartupLocation)element.GetValue(WindowStartupLocationProperty);
|
||||
|
||||
|
||||
public static readonly DependencyProperty ResizeModeProperty = DependencyProperty.RegisterAttached(
|
||||
"ResizeMode", typeof(ResizeMode), typeof(DialogWindowProperty), new PropertyMetadata(ResizeMode.CanResize));
|
||||
public static void SetResizeMode(DependencyObject element, ResizeMode value)
|
||||
=> element.SetValue(ResizeModeProperty, value);
|
||||
public static ResizeMode GetResizeMode(DependencyObject element)
|
||||
=> (ResizeMode)element.GetValue(ResizeModeProperty);
|
||||
|
||||
|
||||
|
||||
public static readonly DependencyProperty WidthProperty = DependencyProperty.RegisterAttached(
|
||||
"Width", typeof(double), typeof(DialogWindowProperty), new PropertyMetadata(double.NaN));
|
||||
public static void SetWidth(DependencyObject element, double value)
|
||||
=> element.SetValue(WidthProperty, value);
|
||||
public static double GetWidth(DependencyObject element)
|
||||
=> (double)element.GetValue(WidthProperty);
|
||||
|
||||
|
||||
|
||||
public static readonly DependencyProperty HeightProperty = DependencyProperty.RegisterAttached(
|
||||
"Height", typeof(double), typeof(DialogWindowProperty), new PropertyMetadata(double.NaN));
|
||||
public static void SetHeight(DependencyObject element, double value)
|
||||
=> element.SetValue(HeightProperty, value);
|
||||
public static double GetHeight(DependencyObject element)
|
||||
=> (double)element.GetValue(HeightProperty);
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
using MAX.Core.Commons;
|
||||
using Prism.Commands;
|
||||
using Prism.Mvvm;
|
||||
using Prism.Services.Dialogs;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace MAX.Framework.Controls;
|
||||
|
||||
public static class IDialogServiceExtension
|
||||
{
|
||||
public static void ShowDialog<TParameter>(this IDialogService dialogService, string name, TParameter parameter, Action<IDialogResult> callback) where TParameter : class
|
||||
{
|
||||
dialogService.ShowDialog(name, new DialogParameters
|
||||
{
|
||||
{"parameter", parameter},
|
||||
}, callback);
|
||||
}
|
||||
public static void Show<TParameter>(this IDialogService dialogService, string name, TParameter parameter, Action<IDialogResult> callback) where TParameter : class
|
||||
{
|
||||
dialogService.Show(name, new DialogParameters
|
||||
{
|
||||
{"parameter", parameter},
|
||||
}, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 确定取消对话框 ViewModel
|
||||
/// </summary>
|
||||
public class ConfirmDialogViewModel : BindableBase, IDialogAware
|
||||
{
|
||||
public ConfirmDialogViewModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private string title = "";
|
||||
private bool _enableConfirm = true;
|
||||
private bool _ShowConfirm = true;
|
||||
private bool _ShowCancel = true;
|
||||
private bool _ShowErrorMsg = true;
|
||||
private string _ErrorMsg = "";
|
||||
private string confirmText = "确定";
|
||||
private string cancelText = "取消";
|
||||
private string backText = "返回";
|
||||
private bool allowEscape = true;
|
||||
private bool allowEnter = true;
|
||||
private bool isLoading = false;
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => title;
|
||||
protected set => SetProperty(ref title, value);
|
||||
}
|
||||
|
||||
public bool AllowEscape
|
||||
{
|
||||
get => allowEscape;
|
||||
set => SetProperty(ref allowEscape, value);
|
||||
}
|
||||
|
||||
public bool AllowEnter
|
||||
{
|
||||
get => allowEnter;
|
||||
set => SetProperty(ref allowEnter, value);
|
||||
}
|
||||
|
||||
public bool IsLoading
|
||||
{
|
||||
get => isLoading;
|
||||
set => SetProperty(ref isLoading, value, () =>
|
||||
{
|
||||
AllowEscape = !value;
|
||||
AllowEnter = !value;
|
||||
EnableConfirm = !value;
|
||||
});
|
||||
}
|
||||
//<UserControl.Resources>
|
||||
// <SolidColorBrush x:Key="RegionBrush" Color="Red"/>
|
||||
// </UserControl.Resources>
|
||||
private SolidColorBrush _Underpaint = new SolidColorBrush(Color.FromRgb(238, 238, 238));
|
||||
/// <summary>
|
||||
/// 背景底色
|
||||
/// </summary>
|
||||
public SolidColorBrush Underpaint
|
||||
{
|
||||
get => _Underpaint;
|
||||
set => SetProperty(ref _Underpaint, value);
|
||||
}
|
||||
|
||||
public event Action<IDialogResult> RequestClose;
|
||||
protected void OnRequestClose(IDialogResult result)
|
||||
{
|
||||
RequestClose?.Invoke(result);
|
||||
}
|
||||
|
||||
public virtual bool CanCloseDialog()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void OnDialogClosed()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool EnableConfirm
|
||||
{
|
||||
get => _enableConfirm;
|
||||
set => SetProperty(ref _enableConfirm, value);
|
||||
}
|
||||
|
||||
public bool ShowConfirm
|
||||
{
|
||||
get => _ShowConfirm;
|
||||
set => SetProperty(ref _ShowConfirm, value);
|
||||
}
|
||||
public bool ShowCancel
|
||||
{
|
||||
get => _ShowCancel;
|
||||
set => SetProperty(ref _ShowCancel, value);
|
||||
}
|
||||
public bool ShowErrorMsg
|
||||
{
|
||||
get => _ShowErrorMsg;
|
||||
set => SetProperty(ref _ShowErrorMsg, value);
|
||||
}
|
||||
|
||||
public string ConfirmText
|
||||
{
|
||||
get => confirmText;
|
||||
set => SetProperty(ref confirmText, value);
|
||||
}
|
||||
public string CancelText
|
||||
{
|
||||
get => cancelText;
|
||||
set => SetProperty(ref cancelText, value);
|
||||
}
|
||||
public string BackText
|
||||
{
|
||||
get => backText;
|
||||
set => SetProperty(ref backText, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误提示
|
||||
/// </summary>
|
||||
public string ErrorMsg
|
||||
{
|
||||
get => _ErrorMsg;
|
||||
set => SetProperty(ref _ErrorMsg, value);
|
||||
}
|
||||
|
||||
public virtual ICommand ConfirmCommand => new DelegateCommand(_Confirm);
|
||||
|
||||
protected virtual void _Confirm()
|
||||
{
|
||||
DialogResult ret = Confirm();
|
||||
if (ret != null)
|
||||
{
|
||||
RequestClose?.Invoke(ret);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual DialogResult Confirm()
|
||||
{
|
||||
return new DialogResult(ButtonResult.OK);
|
||||
}
|
||||
|
||||
public virtual ICommand CancelCommand => new DelegateCommand(_Cancel);
|
||||
|
||||
protected virtual void _Cancel()
|
||||
{
|
||||
DialogResult ret = Cancel();
|
||||
if (ret != null)
|
||||
{
|
||||
RequestClose?.Invoke(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
|
||||
}
|
||||
}
|
||||
protected virtual DialogResult Cancel()
|
||||
{
|
||||
return new DialogResult(ButtonResult.Cancel);
|
||||
}
|
||||
|
||||
public virtual void Loaded(object content)
|
||||
{
|
||||
var bb = Application.Current.TryFindResource("BackgroundBrush") as SolidColorBrush;
|
||||
if (bb != null)
|
||||
{
|
||||
Underpaint = bb;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class AsyncConfirmDialogViewModel : ConfirmDialogViewModel
|
||||
{
|
||||
public override ICommand ConfirmCommand => new AsyncDelegateCommand(_Confirm);
|
||||
|
||||
protected new async Task _Confirm()
|
||||
{
|
||||
DialogResult ret = await Confirm();
|
||||
if (ret != null)
|
||||
{
|
||||
OnRequestClose(ret);
|
||||
}
|
||||
}
|
||||
|
||||
protected new virtual async Task<DialogResult> Confirm()
|
||||
{
|
||||
return await Task.FromResult(new DialogResult(ButtonResult.OK));
|
||||
}
|
||||
}
|
||||
|
||||
public interface IDialogClassParameters
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
/// 确定取消对话框
|
||||
/// </summary>
|
||||
/// <typeparam name="TParameter">参数Model</typeparam>
|
||||
public class ConfirmDialogViewModel<TParameter> : ConfirmDialogViewModel where TParameter : class
|
||||
{
|
||||
protected TParameter Args { get; set; }
|
||||
public override void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
base.OnDialogOpened(parameters);
|
||||
if (parameters.TryGetValue("parameter", out TParameter parameter))
|
||||
{
|
||||
Args = parameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ConfirmDialogViewModel<TParameter, TResult> : ConfirmDialogViewModel where TParameter : class where TResult : DialogResult/*, new()*/
|
||||
{
|
||||
protected TParameter Args { get; set; }
|
||||
public override void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
base.OnDialogOpened(parameters);
|
||||
if (parameters.TryGetValue("parameter", out TParameter parameter))
|
||||
{
|
||||
Args = parameter;
|
||||
}
|
||||
}
|
||||
protected override void _Confirm()
|
||||
{
|
||||
TResult ret = Confirm();
|
||||
if (ret != null)
|
||||
{
|
||||
base.OnRequestClose(ret);
|
||||
}
|
||||
}
|
||||
protected new abstract TResult Confirm();
|
||||
|
||||
protected override void _Cancel()
|
||||
{
|
||||
TResult ret = Cancel();
|
||||
if (ret != null)
|
||||
{
|
||||
base.OnRequestClose(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.OnRequestClose(new DialogResult(ButtonResult.Cancel));
|
||||
}
|
||||
}
|
||||
protected new abstract TResult Cancel();
|
||||
}
|
||||
|
||||
|
||||
//public abstract class ConfirmDialogParameterViewModel : ConfirmDialogViewModel<ConfirmDialogParameterViewModel.Parameter>
|
||||
//{
|
||||
// public abstract class Parameter;
|
||||
//}
|
||||
@@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace MAX.Framework.Extensions;
|
||||
|
||||
public static class StyleExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 合并指定的 <see cref="Style"/>。
|
||||
/// </summary>
|
||||
/// <param name="style1"></param>
|
||||
/// <param name="style2"></param>
|
||||
public static void Merge(this Style style1, Style style2)
|
||||
{
|
||||
if (style1 == null)
|
||||
{
|
||||
throw new ArgumentNullException("style1");
|
||||
}
|
||||
if (style2 == null)
|
||||
{
|
||||
throw new ArgumentNullException("style2");
|
||||
}
|
||||
|
||||
if (style1.TargetType.IsAssignableFrom(style2.TargetType))
|
||||
{
|
||||
style1.TargetType = style2.TargetType;
|
||||
}
|
||||
|
||||
if (style2.BasedOn != null)
|
||||
{
|
||||
style1.Merge(style2.BasedOn);
|
||||
}
|
||||
|
||||
foreach (SetterBase currentSetter in style2.Setters)
|
||||
{
|
||||
style1.Setters.Add(currentSetter);
|
||||
}
|
||||
|
||||
|
||||
foreach (TriggerBase currentTrigger in style2.Triggers)
|
||||
{
|
||||
style1.Triggers.Add(currentTrigger);
|
||||
}
|
||||
|
||||
// This code is only needed when using DynamicResources.
|
||||
foreach (object key in style2.Resources.Keys)
|
||||
{
|
||||
style1.Resources[key] = style2.Resources[key];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 集合是否有值。
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static bool HasValue<T>(this IEnumerable<T> source)
|
||||
{
|
||||
return source != null && source.Any();
|
||||
}
|
||||
|
||||
public static ResourceDictionary FindResourceDictionary(this Style style, object resourceKey)
|
||||
{
|
||||
if (style.Resources != null && style.Resources.Contains(resourceKey))
|
||||
{
|
||||
return style.Resources;
|
||||
}
|
||||
if (style.BasedOn != null)
|
||||
{
|
||||
return style.BasedOn.FindResourceDictionary(resourceKey);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Merge(this ResourceDictionary resourceDictionary, ResourceDictionary mergee)
|
||||
{
|
||||
if (resourceDictionary != null && mergee != null && mergee.Count > 0)
|
||||
{
|
||||
foreach (var key in mergee.Keys)
|
||||
{
|
||||
if (!resourceDictionary.Contains(key))
|
||||
{
|
||||
resourceDictionary.Add(key, mergee[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MAX.Framework.Helpers;
|
||||
|
||||
public static class ObjectHelper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, PropertyInfo> CachedObjectProperties =
|
||||
new();
|
||||
|
||||
public static void TrySetProperty<TObject, TValue>(
|
||||
TObject obj,
|
||||
Expression<Func<TObject, TValue>> propertySelector,
|
||||
Func<TValue> valueFactory,
|
||||
params Type[] ignoreAttributeTypes
|
||||
)
|
||||
{
|
||||
TrySetProperty(obj, propertySelector, x => valueFactory(), ignoreAttributeTypes);
|
||||
}
|
||||
|
||||
public static void TrySetProperty<TObject, TValue>(
|
||||
TObject obj,
|
||||
Expression<Func<TObject, TValue>> propertySelector,
|
||||
Func<TObject, TValue> valueFactory,
|
||||
params Type[] ignoreAttributeTypes
|
||||
)
|
||||
{
|
||||
string cacheKey =
|
||||
$"{obj?.GetType().FullName}-"
|
||||
+ $"{propertySelector}-"
|
||||
+ $"{(ignoreAttributeTypes != null ? "-" + string.Join("-", ignoreAttributeTypes.Select(x => x.FullName)) : "")}";
|
||||
|
||||
PropertyInfo property = CachedObjectProperties.GetOrAdd(
|
||||
cacheKey,
|
||||
(name) =>
|
||||
{
|
||||
if (propertySelector.Body.NodeType != ExpressionType.MemberAccess)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
MemberExpression memberExpression = (MemberExpression)propertySelector.Body;
|
||||
|
||||
PropertyInfo propertyInfo = obj?.GetType()
|
||||
.GetProperties()
|
||||
.FirstOrDefault(
|
||||
x =>
|
||||
x.Name == memberExpression.Member.Name
|
||||
&& x.GetSetMethod(true) != null
|
||||
);
|
||||
|
||||
if (propertyInfo == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
ignoreAttributeTypes != null
|
||||
&& ignoreAttributeTypes.Any(
|
||||
ignoreAttribute => propertyInfo.IsDefined(ignoreAttribute, true)
|
||||
)
|
||||
)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return propertyInfo;
|
||||
}
|
||||
);
|
||||
|
||||
property?.SetValue(obj, valueFactory(obj));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Timer = System.Threading.Timer;
|
||||
|
||||
namespace MAX.Framework.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// 定义一个简单的调度器接口
|
||||
/// </summary>
|
||||
public interface IJob
|
||||
{
|
||||
Task Execute();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 简单调度器帮助类,用于实现简单的调度功能。
|
||||
/// </summary>
|
||||
public class SimpleSchedulerHelper
|
||||
{
|
||||
private readonly Timer _timer;
|
||||
|
||||
public SimpleSchedulerHelper()
|
||||
{
|
||||
_timer = new Timer(DoTime, null, Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
private void DoTime(object obj)
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 启动调度器
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
_timer.Change(10, 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止调度器
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
_timer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
using MAX.Core.Commons;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace MAX.Framework.Helpers;
|
||||
|
||||
public class WinCmdHelper
|
||||
{
|
||||
#region 执行Dos命令
|
||||
|
||||
/// <summary>
|
||||
/// 执行Dos命令
|
||||
/// </summary>
|
||||
/// <param name="cmd">Dos命令及参数</param>
|
||||
/// <param name="isShowCmdWindow">是否显示cmd窗口</param>
|
||||
/// <param name="isCloseCmdProcess">执行完毕后是否关闭cmd进程</param>
|
||||
/// <returns>成功返回true,失败返回false</returns>
|
||||
public static Result ExcuteDosCommand(string cmd, string workdir, bool isShowCmdWindow = false, bool isWaitForExit = false, bool isCloseCmdProcess = true)
|
||||
{
|
||||
Result result = new();
|
||||
try
|
||||
{
|
||||
StringBuilder errString = new();
|
||||
StringBuilder outString = new();
|
||||
Process p = new();
|
||||
p.StartInfo.FileName = "cmd";
|
||||
p.StartInfo.WorkingDirectory = workdir;
|
||||
p.StartInfo.Arguments = "/c " + cmd;
|
||||
p.StartInfo.StandardOutputEncoding = Encoding.UTF8;
|
||||
p.StartInfo.StandardErrorEncoding = Encoding.UTF8;
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
p.StartInfo.RedirectStandardError = true;
|
||||
p.StartInfo.CreateNoWindow = !isShowCmdWindow;
|
||||
p.OutputDataReceived += new DataReceivedEventHandler(delegate (object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
{
|
||||
outString.AppendLine(e.Data);
|
||||
Debug.WriteLine(e.Data);
|
||||
}
|
||||
});
|
||||
p.ErrorDataReceived += new DataReceivedEventHandler(delegate (object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
{
|
||||
errString.AppendLine(e.Data);
|
||||
}
|
||||
});
|
||||
p.Start();
|
||||
p.BeginOutputReadLine();
|
||||
p.BeginErrorReadLine();
|
||||
if (isWaitForExit)
|
||||
{
|
||||
p.WaitForExit();
|
||||
}
|
||||
|
||||
if (isCloseCmdProcess)
|
||||
{
|
||||
p.Close();
|
||||
}
|
||||
if (errString.Length <= 0)
|
||||
{
|
||||
result.Success = true;
|
||||
result.Data = outString.ToString();
|
||||
}
|
||||
Console.WriteLine(string.Format("成功执行Dos命令[{0}]!", cmd));
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("执行命令失败,请检查输入的命令是否正确:" + ex.Message, ex);
|
||||
result.Msg = ex.Message;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void P_ErrorDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 判断指定的进程是否在运行中
|
||||
|
||||
/// <summary>
|
||||
/// 判断指定的进程是否在运行中
|
||||
/// </summary>
|
||||
/// <param name="processName">要判断的进程名称,不包括扩展名exe</param>
|
||||
/// <param name="processFileName">进程文件的完整路径</param>
|
||||
/// <returns>存在返回true,否则返回false</returns>
|
||||
public static bool CheckProcessExists(string processName, string processFileName)
|
||||
{
|
||||
Process[] processes = Process.GetProcessesByName(processName);
|
||||
foreach (Process p in processes)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(processFileName))
|
||||
{
|
||||
if (processFileName == p?.MainModule?.FileName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 结束指定的windows进程
|
||||
|
||||
/// <summary>
|
||||
/// 结束指定的windows进程,如果进程存在
|
||||
/// </summary>
|
||||
/// <param name="processName">进程名称,不包含扩展名</param>
|
||||
/// <param name="processFileName">进程文件完整路径,如果为空则删除所有进程名为processName参数值的进程</param>
|
||||
public static bool KillProcessExists(string processName, string processFileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process[] processes = Process.GetProcessesByName(processName);
|
||||
foreach (Process p in processes)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(processFileName))
|
||||
{
|
||||
if (processFileName == p.MainModule.FileName)
|
||||
{
|
||||
p.Kill();
|
||||
p.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p.Kill();
|
||||
p.Close();
|
||||
}
|
||||
}
|
||||
Console.WriteLine(string.Format("成功结束[{0}]进程!", processes));
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("结束指定的Widnows进程异常:" + ex.Message, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace MAX.Framework.Interfaces;
|
||||
|
||||
public interface IAppClosedHandler
|
||||
{
|
||||
/// <summary> 优先级(优先级越高越先执行) </summary>
|
||||
int Priority { get; }
|
||||
|
||||
/// <summary> 描述信息 </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary> 应用关闭时执行的方法 </summary>
|
||||
/// <param name="parameter"> 参数 </param>
|
||||
/// <exception cref="Exception"/>
|
||||
void AppClosed(AppCloseParameter parameter);
|
||||
}
|
||||
|
||||
public record class AppCloseParameter(bool IsAppInitialized);
|
||||
@@ -0,0 +1,8 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
|
||||
namespace MAX.Framework.Interfaces;
|
||||
|
||||
public interface IAppConfig : ISingletonDependency
|
||||
{
|
||||
T GetValue<T>(string key, T defaultValue = default);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using MAX.Core.DependencyInjection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MAX.Framework.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化接口
|
||||
/// </summary>
|
||||
public interface IAppInitialize : ISingletonDependency, IPriority
|
||||
{
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// App 初始化数据
|
||||
/// </summary>
|
||||
void AppInitialize(IStatusReport statusReport);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化接口(异步)
|
||||
/// </summary>
|
||||
public interface IAppInitializeAsync : ISingletonDependency, IPriority
|
||||
{
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
string Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// App 初始化数据
|
||||
/// </summary>
|
||||
Task AppInitializeAsync(IStatusReport statusReport);
|
||||
}
|
||||
|
||||
public interface IStatusReport
|
||||
{
|
||||
void SetStatus(string status);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace MAX.Framework.Interfaces;
|
||||
|
||||
public interface IPriority
|
||||
{
|
||||
/// <summary>
|
||||
/// 优先级(优先级越高越先执行)
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
using MAX.Core.Infrastructure;
|
||||
using MAX.Core.Logger;
|
||||
using NLog;
|
||||
using System;
|
||||
using LLogLevel = MAX.Core.Logger.LogLevel;
|
||||
using NLogLevel = NLog.LogLevel;
|
||||
|
||||
namespace MAX.Framework.Logger;
|
||||
|
||||
public class NLogger : SingleInstance<NLogger>, ILoggerFacade
|
||||
{
|
||||
private readonly ILogger _log;
|
||||
|
||||
private NLogger()
|
||||
{
|
||||
//Target target = new FileTarget("log1")
|
||||
//{
|
||||
// FileName = $"{FolderConfig.LoggingFolder}/{DateTime.Now:yyyy-MM-dd}.log",
|
||||
//};
|
||||
//LoggingConfiguration config = new();
|
||||
//config.AddRule(NLogLevel.Debug, NLogLevel.Fatal, target);
|
||||
|
||||
//LogManager.Configuration = config;
|
||||
_log = LogManager.GetLogger("GlobalLogger");
|
||||
}
|
||||
|
||||
public bool IsDebugEnabled { get; private set; } = true;
|
||||
|
||||
public void Debug(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Debug, ex, message);
|
||||
}
|
||||
|
||||
public void Debug(string message)
|
||||
{
|
||||
Execute(NLogLevel.Debug, message);
|
||||
}
|
||||
public void Error(Exception ex)
|
||||
{
|
||||
Execute(NLogLevel.Error, ex);
|
||||
}
|
||||
public void Error(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Error, ex, message);
|
||||
}
|
||||
|
||||
public void Error(string message)
|
||||
{
|
||||
Execute(NLogLevel.Error, message);
|
||||
}
|
||||
|
||||
public void Fatal(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Fatal, ex, message);
|
||||
}
|
||||
|
||||
public void Fatal(string message)
|
||||
{
|
||||
Execute(NLogLevel.Fatal, message);
|
||||
}
|
||||
|
||||
public void Info(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Info, ex, message);
|
||||
}
|
||||
|
||||
public void Info(string message)
|
||||
{
|
||||
Execute(NLogLevel.Info, message);
|
||||
}
|
||||
|
||||
public void Warn(Exception ex, string message)
|
||||
{
|
||||
Execute(NLogLevel.Warn, ex, message);
|
||||
}
|
||||
|
||||
public void Warn(string message)
|
||||
{
|
||||
Execute(NLogLevel.Warn, message);
|
||||
}
|
||||
public void Log(string message, LLogLevel level)
|
||||
{
|
||||
NLogLevel lv = NLogLevel.Info;
|
||||
switch (level)
|
||||
{
|
||||
case LLogLevel.Trace:
|
||||
lv = NLogLevel.Trace;
|
||||
break;
|
||||
case LLogLevel.Debug:
|
||||
lv = NLogLevel.Debug;
|
||||
break;
|
||||
case LLogLevel.Info:
|
||||
lv = NLogLevel.Info;
|
||||
break;
|
||||
case LLogLevel.Warn:
|
||||
lv = NLogLevel.Warn;
|
||||
break;
|
||||
case LLogLevel.Error:
|
||||
lv = NLogLevel.Error;
|
||||
break;
|
||||
case LLogLevel.Fatal:
|
||||
lv = NLogLevel.Fatal;
|
||||
break;
|
||||
case LLogLevel.None:
|
||||
lv = NLogLevel.Off;
|
||||
break;
|
||||
}
|
||||
Execute(lv, message);
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
private bool Enabled(NLogLevel level)
|
||||
{
|
||||
if (level > NLogLevel.Debug)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return IsDebugEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行
|
||||
/// </summary>
|
||||
private void Execute(NLogLevel level, Exception ex, string message = "")
|
||||
{
|
||||
if (Enabled(level))
|
||||
{
|
||||
_log.Log(level, ex, message, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 执行
|
||||
/// </summary>
|
||||
private void Execute(NLogLevel level, string message)
|
||||
{
|
||||
if (Enabled(level))
|
||||
{
|
||||
_log.Log(level, message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<UseWPF>true</UseWPF>
|
||||
<NoWarn>NU1608;CS0168;CS1591;CS1574;CS1573;CS1711</NoWarn>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="6.0.2" />
|
||||
<PackageReference Include="Prism.Wpf" Version="8.1.97" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MAX.Core\MAX.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Autofac;
|
||||
using MAX.Core;
|
||||
using MAX.Core.Autofac;
|
||||
using MAX.Core.DependencyInjection;
|
||||
using MAX.Core.Logger;
|
||||
using MAX.Core.Reflections;
|
||||
using MAX.Framework.Logger;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace MAX.Framework;
|
||||
|
||||
public class Startup : IStartup
|
||||
{
|
||||
public int Priority => int.MaxValue - 1;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Register(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterInstance(NLogger.Instance).As<ILoggerFacade>().SingleInstance();
|
||||
|
||||
#region 注册所有IOC接口
|
||||
|
||||
Assembly[] assemblies = AppTypeFinder.Assemblies.ToArray();
|
||||
|
||||
Type typeSingleton = typeof(ISingletonDependency);
|
||||
builder.RegisterAssemblyTypes(assemblies)
|
||||
.Where(a =>
|
||||
typeSingleton.IsAssignableFrom(a)
|
||||
&& a.IsClass
|
||||
&& !a.IsAbstract
|
||||
&& !typeof(INoDependency).IsAssignableFrom(a)
|
||||
)
|
||||
.AsImplementedInterfaces()
|
||||
.AsSelf()
|
||||
.PropertiesAutowired(new CustomPropertySelector())
|
||||
.SingleInstance();
|
||||
|
||||
|
||||
Type typeTransient = typeof(ITransientDependency);
|
||||
builder.RegisterAssemblyTypes(assemblies)
|
||||
.Where(a =>
|
||||
typeTransient.IsAssignableFrom(a)
|
||||
&& a.IsClass
|
||||
&& !a.IsAbstract
|
||||
&& !typeof(INoDependency).IsAssignableFrom(a)
|
||||
)
|
||||
.AsImplementedInterfaces()
|
||||
.AsSelf()
|
||||
.PropertiesAutowired(new CustomPropertySelector())
|
||||
.InstancePerDependency();
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user