以上内容展示了如何手动实现一个简单的依赖注入容器,并使用它来配置和注入依赖项。整体上已经非常清晰和实用,但还有一些优化建议可以提高代码的灵活性和可维护性:
优化建议
-
类型安全注册和解析: 目前的实现依赖于
Func<object>
,在解析时需要进行强制转换,可能会导致运行时错误。我们可以使用泛型来提高类型安全性。 -
生命周期管理: 当前的实现每次解析都会创建新的实例。如果需要支持单例或其他生命周期管理,可以扩展容器。
-
自动属性注入: 可以实现自动属性注入,而不是手动配置每个属性。
优化后的实现
1. 增强的依赖注入容器
csharp
public class SimpleContainer
{
private readonly Dictionary<Type, Func<object>> _registrations = new Dictionary<Type, Func<object>>();
private readonly Dictionary<Type, object> _singletons = new Dictionary<Type, object>();
public void Register<TService, TImplementation>() where TImplementation : TService
{
_registrations[typeof(TService)] = () => CreateInstance(typeof(TImplementation));
}
public void RegisterSingleton<TService, TImplementation>() where TImplementation : TService
{
var instance = CreateInstance(typeof(TImplementation));
_singletons[typeof(TService)] = instance;
_registrations[typeof(TService)] = () => instance;
}
public TService Resolve<TService>()
{
return (TService)_registrations[typeof(TService)]();
}
private object CreateInstance(Type type)
{
var ctor = type.GetConstructors().First();
var parameters = ctor.GetParameters().Select(p => Resolve(p.ParameterType)).ToArray();
return Activator.CreateInstance(type, parameters);
}
}
2. 配置和使用容器
csharp
using System;
using System.Windows;
namespace Zhaoxi.BMS
{
public partial class App : Application
{
public static SimpleContainer Container { get; private set; }
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ConfigureContainer();
var mainWindow = Container.Resolve<MainWindow>();
mainWindow.Show();
}
private void ConfigureContainer()
{
Container = new SimpleContainer();
Container.Register<MainWindow, MainWindow>();
Container.Register<MainViewModel, MainViewModel>();
Container.Register<ICommand, Command>();
}
}
}
3. 支持构造函数注入的 MainViewModel
csharp
using System.Collections.Generic;
using System.Windows.Input;
namespace Zhaoxi.BMS.ViewModels
{
public class MainViewModel : NotifyBase
{
public List<string> BatteryGroup { get; set; } = new List<string>();
public ICommand NavCommand { get; }
public MainViewModel(ICommand navCommand)
{
NavCommand = navCommand;
if (NavCommand is Command command)
{
command.DoExecute = SwitchPage;
}
for (int i = 0; i < 100; i++)
{
BatteryGroup.Add(i.ToString());
}
}
private void SwitchPage(object page)
{
var type = Assembly.GetExecutingAssembly().GetType($"Zhaoxi.BMS.Views.Pages.{page}");
PageObject = Activator.CreateInstance(type);
}
private object _pageObject;
public object PageObject
{
get { return _pageObject; }
set { SetProperty(ref _pageObject, value); }
}
}
}
总结
通过上述优化,我们提高了代码的类型安全性和灵活性,并且实现了单例的生命周期管理。同时,构造函数注入的方式使得代码更容易测试和维护。如果有更多复杂的需求,可以考虑引入生命周期管理、属性注入等高级功能,但这些优化已经展示了手动实现依赖注入的一些核心理念和最佳实践。