c#之Stylet开发文档 14.2 StyletIoC配置

StyletIoC 配置

在这里,您将学习如何创建一个新的StyletIoC容器,并在其中注册您的服务。

入门-生成器

若要创建容器,您必须创建一个新的StyletIoCBuilder,并在其上注册所有服务。StyletIoCBuilder.BuildContainer()将被调用,因此您不需要调用它来构建容器。

例如:

// First, create the builder
var builder = new StyletIoCBuilder();

// Configure the builder
builder.Bind<IVehicle>().To<HotHatchback>();

// The container is then built for you

// Now you can use this to resolve instances of services
var vehicle = ioc.Get<IVehicle>();

创建类型的不同方法

如前所述,StyletIoC的目的是接受对服务类型的请求,并使用您使用StyletIoCBuilder配置的规则返回实现该服务的某个实例。不过,它可以使用几种不同的技术来创建该实例。

类型绑定

最简单的称为“类型绑定”。你告诉它服务类型,以及实现该服务的类型,它就会知道如何构造该类型本身。例如:

builder.Bind<IVehicle>().To<HotHatchback>();

这条消息告诉StyletIoC“每当我向您请求IVehicle时,请使用适当的构造函数创建一个新的HotHatchback,并传入所有必要的依赖项”。

当然,您可以将服务绑定到其自身,只要该服务是具体类型即可。这被称为“自我绑定”。例如:

builder.Bind<HotHatchback>().To<HotHatchback>();
// Or, more clearly:
builder.Bind<HotHatchback>().ToSelf();

这条消息告诉StyletIoC“每当我向你索要一个HotHatchback时,请给我一个已经填充了所有依赖项的HotHatchback”。

如果您愿意,也可以使用非通用重载:

builder.Bind(typeof(IVehicle)).To(typeof(HotHatchback));

工厂绑定

如果出于某种原因,您想告诉StyletIoC如何构造您的类型,您可以向它传递一个要调用的委托。这被称为“工厂绑定”。例如:

builder.Bind<IVehicle>().ToFactory(container => new HotHatchback());

container参数有一个IContainer,如果构造函数需要注入依赖项,则可以使用它,例如:

builder.Bind<IVehicle>().ToFactory(container => new HotHatchback(container.Get<Engine>()));

当然,自我绑定在这里也起作用:

builder.Bind<HotHatchback>().ToFactory(container => new HotHatchback());

实例绑定

您可以自己构造一个类型的实例,并将其提供给IoC容器。这对于配置对象之类的事情可能很有用。例如:

builder.Bind<IVehicle>().ToInstance(new HotHatchback());

实例绑定是自动单例的——容器不知道如何构造该类型的新实例,因此必须始终返回相同的实例。

默认情况下,IoC容器在被释放时会释放IDisposable实例类型,但您可以使用.ToInstance(foo).DisposeWithContainer(false);进行配置。

不同的范围

瞬态范围

默认情况下,StyletIoC每次请求时都会创建一个给定类型的新实例,这被称为“瞬态范围”。请参阅:

var car1 = ioc.Get<IVehicle>();
var car2 = ioc.Get<IVehicle>();

// The following statement will succeed.
Assert.AreNotEqual(car1, car2);

IoC容器不会处理IDisposable瞬态类型——它不会声称对它们的所有权,也不知道什么时候应该处理它们。

单例范围

然而,您也可以告诉它永远只创建一个服务实例,并在每次请求时返回该实例。这被称为“singleton scope”,如果您的应用程序确实有singleton(大多数都有),这将非常有用,因为它可以使您免于拥有传统的singleton对象,而传统的singleton对象在单元测试中很难模拟。

builder.Bind<IConfigurationManager>().To<ConfigurationManager>().InSingletonScope();
var ioc = builder.BuildContainer();

var configManager1 = ioc.Get<IConfigurationManager>();
var configManager2 = ioc.Get<IConfigurationManager();

// The following statement will succeed.
Assert.AreEqual(configManager1, configManager2);

当然,这也适用于工厂绑定(其中工厂将只被调用一次):

builder.Bind<IConfigurationManager>().ToFactory(container => new ConfigurationManager()).InSingletonScope();

请注意,singleton的作用域是定义它们的绑定处,请参阅:

builder.Bind<IConfigurationManager>().To<ConfigurationManager>().InSingletonScope();
builder.Bind<ConfigurationManager>().ToSelf();

var ioc = builder.BuildContainer();

var configManager1 = ioc.Get<IConfigurationManager>();
var configManager2 = ioc.Get<ConfigurationManager>();

// The following statement will succeed.
Assert.AreNotEqual(configManager1, configManager2);

如果您真的希望这两者返回相同的实例,可以使用以下技术:

builder.Bind<ConfigurationManager>().And<IConfigurationManager>().To<ConfigurationManager>().InSingletonScope();

IoC容器在被处理时将处理IDisposable单例。

将多个类型绑定到单个服务

到目前为止,我们已经尝试将单个类型绑定到单个服务。但事实并非如此。您可以将多个类型绑定到单个服务,例如:

interface IVehicle { ... }
class HotHatchback : IVehicle { ... }
class OldBanger : IVehicle { ... }

builder.Bind<IVehicle>().To<HotHatchback>();
builder.Bind<IVehicle>().To<OldBanger>();

var ioc = builder.BuildContainer();

// This will throw an exception
ioc.Get<IVehicle>();

// This will return { new HotHatchback(), new OldBanger() }
IEnumerable<IVehicle> vehicles = ioc.GetAll<IVehicle>();

正如你所看到的,如果你想提取一个项目数组,你需要使用IContainer.GetAll-如果你尝试用IContainer.Get提取一个IVehicle,StyletIoC不知道该给你哪个,所以它抛出了一个异常。

这也适用于构造函数和参数注入,请参阅:

class Garage
{
   public Garage(IEnumerable<IVehicle> vehicles) { ... }
}

// And

class Garage
{
   [Inject]
   public IEnumerable<IVehicle> Vehicles { get; set; }
}

绑定泛型类型

StyletIoC处理与普通类型相同的绑定泛型类型(其中类型参数的确切类型是已知的),例如:

interface IValidator<T> { ... }
class IntValidator : IValidator<int> { ... }
builder.Bind<IValidator<int>>().To<IntValidator>();

并且

interface IValidator<T> { ... }
class Validator<T> : IValidator<T> { ... }
builder.Bind<IValidator<int>>().To<Validator<int>>();

当您想要为类型参数的确切类型未知的泛型类型创建绑定时,乐趣就开始了,例如:

interface IValidator<T> { ... }
class Validator<T> : IValidator<T> { ... }
builder.Bind(typeof(IValidator<>)).To(typeof(Validator<>));

var ioc = builder.BuildContainer();

var intValidator = ioc.Get<IValidator<int>>(); // 返回一个 Validator<int>

服务及其实现可以具有任意多的类型参数,但它们必须具有相同数量的类型参数(如果仔细考虑,这是有意义的)。然而,类型参数可以以任何顺序出现:

interface ISomeInterface<T, U> { ... }
class SomeClass<U, T> : ISomeInterface<T, U> { ... }
builder.Bind(typeof(ISomeInterface<,>)).To(typeof(SomeClass<,>));

StyletIoC不考虑类型约束-如果您有一个interface IMyInterface<T> where T:class并且请求IMyInterface<int>,你将会得到一个异常。

自动绑定

StyletIoC能够自动为您创建绑定。

自动绑定所有具体类型

自动绑定意味着,如果您请求尚未向Stylet注册的具体类型,Stylet将尝试将其构造为临时实例。它仅适用于您指定的程序集中的类型:StyletIoCBuilder.Assemblies中的类型,以及传递给Autobind方法的任何程序集中的那些类型。

请注意,显式绑定始终优先于自动绑定。

将mscorlib之类的程序集传递给Autobind是一个坏主意,否则Stylet将尝试实例化System.String之类的类型。

builder.Autobind();

这在MVVM应用程序中非常有用,因为它允许StyletIoC解析任何ViewModel。Stylet引导程序调用Autobind(),这意味着默认情况下启用自动绑定。

将服务绑定到所有实现

您还可以将服务绑定到实现它的所有类型,例如:

interface IVehicle { ... }
class HotHatchback : IVehicle { ... }
class OldBanger : IVehicle { ... }

builder.Bind<IVehicle>().ToAllImplementations();

var ioc = builder.BuildContainer();

IEnumerable<IVehicle> vehicles = ioc.GetAll<IVehicle>(); // Returns { new HotHatchback(), new OldBanger() }

还有一些重载允许您指定要搜索的程序集。

这本身可能很有用(想想寻找所有插件),但与未绑定泛型结合时特别有用。例如:

interface IValidator<T> { ... }
class IntValidator : IValidator<int> { ... }
class StringValidator : IValidator<string> { ... }

builder.Bind(typeof(IValidator<>)).ToAllImplementations();

var ioc = builder.BuildContainer();

var intValidator = ioc.Get<IValidator<int>>(); // Returns an IntValidator
var stringValidator = ioc.Get<IValidator<string>>(); // Returns a StringValidator

如果您想要更复杂的绑定规则,StyletIoC不会为您提供API——您自己几乎不需要付出任何努力,提供API只是增加了许多复杂性,但收获甚微。

然而,StyletIoC确实在Type上定义了两个扩展方法,这可能会使您的生活更轻松:

// 返回所有基础类型
someType.GetBaseTypes();

// 返回所有基础类型和接口
someType.GetBaseTypesAndInterfaces();

// 如果 someType 实现了 someServiceType,则返回 true
someType.Implements(someServiceType)
// 还考虑了泛型——所以这是真的:
typeof(Validator<int>>.Implements(typeof(IValidator<>));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Stylet DataGrid 是一个用于 WPF 应用程序的开源控件,用于显示和编辑数据。它提供了丰富的功能和灵活的样式选项,可以满足不同应用程序的需求。 Stylet DataGrid 可以方便地与 ViewModel 和数据模型绑定,通过绑定实现数据的展示和编辑。它支持自动列生成,根据数据源的属性动态生成列,并将数据源的数据填充到相应的单元格中。开发人员可以通过设置列的属性来定义列的样式、宽度、绑定属性等,从而实现个性化的显示效果。 Stylet DataGrid 还提供了丰富的交互功能,例如排序、筛选、分组等。用户可以通过点击列标题实现对数据的排序,通过输入筛选条件快速找到特定数据,还可以根据某一列的值对数据进行分组展示。这使得用户可以更方便地对数据进行操作和查找。 此外,Stylet DataGrid 还支持样式的自定义。用户可以通过修改样式模板来改变 DataGrid 的外观,例如调整背景颜色、字体样式、边框样式等,以适应不同的界面风格和需求。 总之,Stylet DataGrid 是一个功能丰富、灵活性强的数据展示和编辑控件,可以方便地将数据展示和用户交互功能集成到 WPF 应用程序中,提供更好的用户体验。 ### 回答2: DataGrid是一种常见的用户界面控件,用于展示和处理数据。Stylet是一个C#的轻量级MVVM库,用于简化WPF应用程序的开发。 在Stylet中使用DataGrid控件很简单。首先,我们需要在XAML中定义一个DataGrid元素,并为其指定一个名称,以便在代码中引用它。例如: ```xaml <DataGrid x:Name="MyDataGrid" /> ``` 然后,在ViewModel中,我们可以使用Stylet的属性绑定功能,将数据与DataGrid关联起来。首先,在ViewModel中定义一个集合属性,用于存储要显示的数据。例如: ```csharp private BindableCollection<MyDataModel> _myData; public BindableCollection<MyDataModel> MyData { get { return _myData; } set { SetAndNotify(ref _myData, value); } } ``` 然后,在ViewModel的构造函数中,我们可以初始化这个集合,并将其赋值给DataGrid的ItemsSource属性,从而将数据与DataGrid绑定起来。例如: ```csharp public MyViewModel() { // 初始化数据集合 MyData = new BindableCollection<MyDataModel>(); // 将数据集合赋值给DataGrid MyDataGrid.ItemsSource = MyData; } ``` 现在,我们可以在界面上看到DataGrid显示了ViewModel中的数据。我们还可以通过DataGrid的其他属性,如AutoGenerateColumns、ColumnDefinitions等,来定制DataGrid的样式和行为。 总结起来,使用Stylet在WPF应用程序中使用DataGrid控件很方便,只需要定义好DataGrid元素和ViewModel中的数据集合,并将它们绑定起来即可。通过Stylet的属性绑定功能,我们可以很容易地控制DataGrid的样式和行为,从而实现需求。 ### 回答3: Stylet 是一个适用于 WPF 和 Xamarin.Forms 的开发框架,它提供了一种简洁、灵活的方式来构建高效的 MVVM 应用程序。 Stylet 提供了一种名为 DataGrid 的控件,用于在应用程序中显示和编辑数据。DataGrid 是一个用于显示表格数据的强大控件,可以轻松地对数据进行排序、筛选和分页等操作。Stylet 的 DataGrid 采用了 MVVM 模式,使得数据与界面的耦合度更低,并且开发者可以通过绑定属性和命令来管理控件的行为。 使用 Stylet 的 DataGrid 可以实现各种功能,例如: 1. 显示数据:DataGrid 可以从 ViewModel 中获取数据,并以表格形式显示在界面上,包括文本、图像等数据类型。 2. 编辑数据:DataGrid 提供了各种编辑模式,可以让用户直接在表格中编辑数据,包括文本框、下拉列表、日期选择等控件。 3. 排序和筛选:DataGrid 允许用户对表格数据进行排序和筛选操作,通过点击列标题可以按照特定的列进行排序,还可以根据条件进行筛选。 4. 分页:DataGrid 支持分页功能,可以将大量数据分成多个页面显示,展示方便,提高用户体验。 5. 样式定制:DataGrid 允许开发者通过自定义样式来定制表格的外观,包括行、列、单元格的样式等。 总之,Stylet 的 DataGrid 提供了一个强大而灵活的方式来处理表格数据,使得应用程序开发更加高效和可靠。它的MVVM模式和丰富的功能使得开发者能够更好地管理和展示数据,并且方便用户进行交互和编辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值