Cru代码.IoC来救援

Ang*_*ker 21 .net c# maintainability ioc-container

问题有关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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

对此:

var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper()); 
Run Code Online (Sandbox Code Playgroud)

问题:

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

Jac*_*cob 9

要使您的第二个代码片段起作用,NotifyPropertyChangedWrapper肯定必须使用反射(或dynamic)来生成一个类,该类提供与其兼容的接口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...
}
Run Code Online (Sandbox Code Playgroud)

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