粗俗的代码。国际奥委会的救援

发布于 2024-10-07 04:00:29 字数 985 浏览 5 评论 0原文

在问题中 关于 IoC 容器的有用性,获奖提交者提到,使用 IoC 容器,您可以采取以下措施

public class UglyCustomer : INotifyPropertyChanged
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            string oldValue = _firstName;
            _firstName = value;
            if(oldValue != value)
                OnPropertyChanged("FirstName");
        }
    }

    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set
        {
            string oldValue = value;
            _lastName = value;
            if(oldValue != value)
                OnPropertyChanged("LastName");
        }
    }
}

var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper()); 

问题:

  • 哪个神奇的 IoC 容器提供了这种好处?
  • 一个实现这个的例子?
  • 有什么缺点吗?
  • 在一个具有复杂依赖关系的项目中,当我尝试将数据绑定应用到这些对象时,我会哭吗?

In question about usefulness of IoC Container, the winning submitter mentioned that with an IoC container you can take this:

public class UglyCustomer : INotifyPropertyChanged
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            string oldValue = _firstName;
            _firstName = value;
            if(oldValue != value)
                OnPropertyChanged("FirstName");
        }
    }

    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set
        {
            string oldValue = value;
            _lastName = value;
            if(oldValue != value)
                OnPropertyChanged("LastName");
        }
    }
}

to this:

var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper()); 

Questions:

  • Which magic IoC container provides this goodness?
  • An example implementing this?
  • Any downsides?
  • In a project with complex dependencies, will I be crying when I try to apply data binding to these objects?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦途 2024-10-14 04:00:29

为了让您的第二个代码片段正常工作,NotifyPropertyChangedWrapper 肯定必须使用反射(或动态)来生成一个类,该类提供与 Customer 兼容的接口> 并实现自动属性通知。不应该有任何数据绑定问题,但会有一点开销。

使用动态对象的简化实现可能如下所示:

public class NotifyPropertyChangedWrapper<T> 
    : DynamicObject, INotifyPropertyChanged
{
    private T _obj;

    public NotifyPropertyChangedWrapper(T obj)
    {
        _obj = obj;
    }

    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        result = typeof(T).GetProperty(binder.Name).GetValue(_obj);
        return true;
    }

    // If you try to set a value of a property that is
    // not defined in the class, this method is called.
    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        typeof(T).GetProperty(binder.Name).SetValue(_obj, value);
        OnPropertyChanged(binder.Name);
        return true;
    }

    // Implement OnPropertyChanged...
}

显然,任何使用这些对象之一的代码都将失去任何静态类型安全性。另一种选择是生成一个实现与被包装的类相同的接口的类。网络上有很多这方面的例子。主要要求是您的客户必须是一个接口,或者需要其所有属性都是虚拟的。

For your second code snippet to work, NotifyPropertyChangedWrapper would certainly have to use reflection (or dynamic) to generate a class that provides an interface compatible with Customer and implements the automatic property notification. There shouldn't be any data binding issues, but there would be a little overhead.

An simplified implementation that uses a dynamic object could look something like this:

public class NotifyPropertyChangedWrapper<T> 
    : DynamicObject, INotifyPropertyChanged
{
    private T _obj;

    public NotifyPropertyChangedWrapper(T obj)
    {
        _obj = obj;
    }

    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        result = typeof(T).GetProperty(binder.Name).GetValue(_obj);
        return true;
    }

    // If you try to set a value of a property that is
    // not defined in the class, this method is called.
    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        typeof(T).GetProperty(binder.Name).SetValue(_obj, value);
        OnPropertyChanged(binder.Name);
        return true;
    }

    // Implement OnPropertyChanged...
}

Obviously, any code that consumes one of these objects would lose any static type safety. The other option is to generate a class implementing the same interface as the class being wrapped. There are lots of examples for this on the web. The main requirement is that your Customer would have to either be an interface or it would need all of its properties to be virtual.

薄荷港 2024-10-14 04:00:29

以通用方式执行此操作(即实现 INotifyPropertyChanged 的​​单段代码
对于任何类)使用代理。有很多实现可以通过 Castle.DynamicProxy 或 < a href="http://www.google.com/search?hl=en&q=linfu+INotifyPropertyChanged" rel="nofollow">LinFu 或 Unity。这些代理库在 IoC 容器中具有良好的支持,例如 DynamicProxy 与 Castle Windsor 具有良好的集成,而 Unity 拦截(或无论它的名称)显然与 Unity 容器具有良好的集成。

To do this in a generic way (i.e. a single piece of code implementing INotifyPropertyChanged
for any class) use a proxy. There are lots of implementations around to do this with Castle.DynamicProxy or LinFu or Unity. These proxy libraries have good support in IoC containers, for example DynamicProxy has good integration with Castle Windsor and Unity interception (or whatever it's called) has obviously good integration with the Unity container.

蓝礼 2024-10-14 04:00:29

如果您正在寻找自动生成可绑定对象的特定解决方案,您应该查看 PropertyChanged.Fody (之前通知PropertyWeaver)。这将重写实现 INotifyPropertyChanged 的​​类以包含通知代码。 github 页面上有一个示例。

在我看来,这比使用建议的 IOC 容器解决方案更简洁。但是,它是特定于 INotifyPropertyChanged 绑定的库,因此不适用于通用解决方案,正如您的链接问题中所讨论的那样。

If you are looking for a specific solution for auto-generating bindable objects you should look at PropertyChanged.Fody (previously NotifyPropertyWeaver). This rewrites classes implementing INotifyPropertyChanged to include the notification code. There is an example on the github page.

In my opinion this is neater than using the proposed IOC container solution. However, it is a library specific to INotifyPropertyChanged binding so is not applicable as a general solution, as was being discussed in your linked question.

眼眸 2024-10-14 04:00:29

我从未使用过它,但据说您可以使用 PostSharp 创建类似的东西。

I've never used it, but you can supposedly create something like this using PostSharp.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文