C# 在顶层使用DependencyInjection,如何在体系结构中传递服务?
使用诸如Unity、AutoFac或其他IOC容器,您必须注册并解析IInterface以获取实例。这是您在应用程序类中执行的所有操作的根 完成注册/解析操作后,我将创建我的MainController并向其传递所有解析服务,如:C# 在顶层使用DependencyInjection,如何在体系结构中传递服务?,c#,.net,mvvm,dependency-injection,viewmodel,C#,.net,Mvvm,Dependency Injection,Viewmodel,使用诸如Unity、AutoFac或其他IOC容器,您必须注册并解析IInterface以获取实例。这是您在应用程序类中执行的所有操作的根 完成注册/解析操作后,我将创建我的MainController并向其传递所有解析服务,如: protected void Application_Start(object sender, EventArgs e) { var builder = new ContainerBuilder(); builder.Register<IUse
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.Register<IUserService1, UserService1>();
builder.Register<IUserService2, UserService2>();
builder.Register<IUserService3, UserService3>();
builder.Register<IAnotherService, AnotherService>();
// And many more Services...
_container = builder.Build();
var userService1 = _container.Resolve<IUserService1>();
var userService2 = _container.Resolve<IUserService2>();
var userService3 = _container.Resolve<IUserService3>();
var anotherService = _container.Resolve<IAnotherService>();
var vm = new MainController(userService1,userService2,userService3,anotherService)
}
public class MainController
{
private UserController1 _userVM1;
private UserController2 _userVM2;
private UserController3 _userVM3;
public MainController(IUserService1 userService1,IUserService2 userService2,IUserService3 userService3,anotherService)
{
_userVM1 = new UserController1(userService1,anotherService);
_userVM2 = new UserController2(userService2,...,...);
_userVM3 = new UserController3(userService3,...,...,...);
}
}
// Such a Controller class needs to be created 10 times... and what I do here is typical for all Controllers driving the GUI
public class UserController1
{
private readonly IUserService1 _userService1;
public UserController1(IUserService1 userService1,IAnotherService anotherService)
{
_userService1 = userService1;
//Bind data to GUI
UserData1Collection = ConvertModelIntoViewModelCollection(userService1,anotherService);
}
public ObservableCollection<UserData1> UserData1Collection { get; set; }
private ObservableCollection<UserData1ViewModel> ConvertModelIntoViewModelCollection(IAnotherService anotherService)
{
var userData1ViewModelCollection = new ObservableCollection<UserData1ViewModel>();
_userService1.GetUserData1().ForEach(user =>
{
userData1ViewModelCollection.Add(new UserData1ViewModel(user, anotherService,...));
});
return userData1ViewModelCollection;
}
}
受保护的无效应用程序\u启动(对象发送方,事件参数e)
{
var builder=new ContainerBuilder();
builder.Register();
builder.Register();
builder.Register();
builder.Register();
//还有更多的服务。。。
_container=builder.Build();
var userService1=_container.Resolve();
var userService2=_container.Resolve();
var userService3=_container.Resolve();
var anotherService=_container.Resolve();
var vm=新的主控制器(userService1、userService2、userService3、其他服务)
}
公共类主控制器
{
私有用户控制器1 _userVM1;
私有用户控制器2_userVM2;
私有用户控制器3_userVM3;
公共主控制器(IUserService1用户服务1、IUserService2用户服务2、IUserService3用户服务3、其他服务)
{
_userVM1=新的UserController1(userService1,另一个服务);
_userVM2=新的UserController2(userService2,…);
_userVM3=新的UserController3(userService3,…);
}
}
//这样的控制器类需要创建10次。。。我在这里所做的是所有驱动GUI的控制器的典型操作
公共类UserController1
{
专用只读IUserService1_userService1;
公共用户控制器1(IUserService1 userService1,iOnotherService另一个服务)
{
_userService1=userService1;
//将数据绑定到GUI
UserData1Collection=ConvertModelIntoViewModelCollection(userService1,另一个服务);
}
公共ObservableCollection UserData1集合{get;set;}
私有ObservableCollection ConvertModelIntoViewModelCollection(iOnotherService另一个服务)
{
var userData1ViewModelCollection=新的observeCollection();
_userService1.GetUserData1().ForEach(用户=>
{
添加(新的UserData1ViewModel(用户,另一个服务,…);
});
返回userData1ViewModelCollection;
}
}
现在的问题是:
有很多通过/通过的服务,因为我必须调用服务,例如,当viewmodels的属性通过失去对gui控件的关注而改变时
我这样做行吗?你觉得有什么缺点吗?或者你会怎么做
更新
这是对我恶习的一次大规模攻击:p
启动时受保护的覆盖无效(StartupEventArgs e)
{
IContainerBuilder=新的ContainerBuilder();
//首先登记所有现有服务
builder.Register();
builder.Register();
builder.Register();
builder.Register();
builder.Register();
builder.Register();
IContainer_container=builder.Build();
//然后注册所有需要先前注册的服务的控制器
IControllerFactory=新的ControllerFactory(建筑商);
IDailyPlanner controller1=factory.Create();
IWeeklyPlanner controller2=factory.Create();
SchoolclassAdministrationViewModel控制器3=factory.Create();
//然后注册mainViewModel(MainController),它应该包含所有的服务和所有的控制器…哇,这是一个巨大的Ctor参数计数…这是纯的吗?你的意思是这样吗???
MainViewModel MainViewModel=_container.Resolve();
//MainWindow MainWindow=_container.Resolve();
//mainWindow.DataContext=mainViewModel;
//mainWindow.ShowDialog();
}
公共类控制器工厂:IControllerFactory
{
专用只读IContainerBuilder\u builder;
专用只读IContainer\u容器;
///
///使用IOC容器注册所有控制器
///
公共控制器工厂(IContainerBuilder)
{
_建筑商=建筑商;
_builder.Register();
_builder.Register();
_builder.Register();
_容器=_builder.Build();
}
///
///返回给定类型的实例
///
公共文件不能创建()
{
返回_container.Resolve();
}
}
更新2:
现在,我更改了MainViewModel接受IControllerFactory作为参数的代码,并将以下两行代码添加到App类中:
builder.Register<IControllerFactory, ControllerFactory>();
builder.Register<IContainerBuilder, ContainerBuilder>();
builder.Register();
builder.Register();
这样我就不需要传递MainViewModel中的所有控制器,而是MainViewModel从工厂获取控制器实例
我能在这里做些更好的事吗?或者这是一个可以接受的好解决方案?我对DI完全没有经验,所以我问:)
更新3
好的,我做了一些代码重构,并为其他人做了评论,以便他们了解最终的解决方案:
protected override void OnStartup(StartupEventArgs e)
{
IContainerBuilder builder = new ContainerBuilder();
// Firstly Register ALL existing Services
builder.Register<IAdminService, AdminService>();
builder.Register<IDocumentService, DocumentService>();
builder.Register<ILessonPlannerService, LessonPlannerService>();
builder.Register<IMediator, Mediator>();
builder.Register<IMainRepository, MainRepository>();
builder.Register<IControllerFactory, ControllerFactory>();
builder.Register<IDailyPlanner, LessonPlannerDailyViewModel>();
builder.Register<IWeeklyPlanner, LessonPlannerWeeklyViewModel>();
// Just for visual separation THEN register the MainController driving all other Controllers created via the IControllerFactory
builder.Register<MainViewModel>();
// Build the container
IContainer container = builder.Build();
// THEN Register the MainController which should take ALL IServices and the IFactory
MainViewModel mainViewModel = container.Resolve<MainViewModel>();
// LATER in the mainViewModel`s Ctor you can create all 10 Controller instances with the IControllerFactory like this
// _dailyPlannerController = controllerFactory.Create<IDailyPlanner>();
MainWindow mainWindow = new MainWindow();
mainWindow.DataContext = mainViewModel;
mainWindow.ShowDialog();
}
public class ControllerFactory : IControllerFactory
{
private readonly IContainer _container;
/// <summary>
/// Takes the IOC container to resolve all Controllers
/// </summary>
public ControllerFactory(IContainer container)
{
_container = container;
}
/// <summary>
/// Returns an Instance of a given Type
/// </summary>
public T Create<T>()
{
return _container.Resolve<T>();
}
}
启动时受保护的覆盖无效(StartupEventArgs e)
{
IContainerBuilder=新的ContainerBuilder();
//首先登记所有现有服务
builder.Register();
builder.Register();
builder.Register();
builder.Register();
builder.Register();
builder.Register();
builder.Register();
builder.Register();
//仅为了视觉分离,然后注册主控制器,驱动通过IControl创建的所有其他控制器
protected override void OnStartup(StartupEventArgs e)
{
IContainerBuilder builder = new ContainerBuilder();
// Firstly Register ALL existing Services
builder.Register<IAdminService, AdminService>();
builder.Register<IDocumentService, DocumentService>();
builder.Register<ILessonPlannerService, LessonPlannerService>();
builder.Register<IMediator, Mediator>();
builder.Register<IMainRepository, MainRepository>();
builder.Register<IControllerFactory, ControllerFactory>();
builder.Register<IDailyPlanner, LessonPlannerDailyViewModel>();
builder.Register<IWeeklyPlanner, LessonPlannerWeeklyViewModel>();
// Just for visual separation THEN register the MainController driving all other Controllers created via the IControllerFactory
builder.Register<MainViewModel>();
// Build the container
IContainer container = builder.Build();
// THEN Register the MainController which should take ALL IServices and the IFactory
MainViewModel mainViewModel = container.Resolve<MainViewModel>();
// LATER in the mainViewModel`s Ctor you can create all 10 Controller instances with the IControllerFactory like this
// _dailyPlannerController = controllerFactory.Create<IDailyPlanner>();
MainWindow mainWindow = new MainWindow();
mainWindow.DataContext = mainViewModel;
mainWindow.ShowDialog();
}
public class ControllerFactory : IControllerFactory
{
private readonly IContainer _container;
/// <summary>
/// Takes the IOC container to resolve all Controllers
/// </summary>
public ControllerFactory(IContainer container)
{
_container = container;
}
/// <summary>
/// Returns an Instance of a given Type
/// </summary>
public T Create<T>()
{
return _container.Resolve<T>();
}
}
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.Register<IUserService1, UserService1>();
builder.Register<IUserService2, UserService2>();
builder.Register<IUserService3, UserService3>();
builder.Register<IAnotherService, AnotherService>();
builder.Register<MainController, MainController>();
// And many more Services...
_container = builder.Build();
//let the container inject all the required dependencies into MainController..
var vm = _container.Resolve<MainController>();
}