C# 在顶层使用DependencyInjection,如何在体系结构中传递服务?

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

使用诸如Unity、AutoFac或其他IOC容器,您必须注册并解析IInterface以获取实例。这是您在应用程序类中执行的所有操作的根

完成注册/解析操作后,我将创建我的MainController并向其传递所有解析服务,如:

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

  • 你是那样想的吗

  • 顺便说一句,为什么我要在工厂做那个控制器?那么为什么不是一个服务工厂呢。。。然后我们回到ServiceLocator

  • 如何在MainViewModel中获得控制器实例?通过使用许多附加参数扩展MVM的构造函数?最后有30个情人

  • 启动时受保护的覆盖无效(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>();
    }