Как я могу избежать отдельного пользовательского TypeDescriptorProvider для каждого из моих классов? - PullRequest
1 голос
/ 06 октября 2009

Я добавил в свой проект функциональность, которая позволяет пользователям добавлять свои собственные свойства к объектам. Для этого я создал свой собственный TypeDescriptor , PropertyDescriptor и TypeDescriptorProviders и т. Д. И т. Д. И т. Д.

Вот моя проблема. Прямо сейчас у меня все это работает, но пришлось создать отдельный TypeDescriptionProvider для каждого типа объекта объекта, который может иметь пользовательские свойства. Вот как выглядят мои TypeDescriptionProviders

//type AClass Custom Provider
class AClassTypeProvider : TypeDescriptionProvider
{
    private static TypeDescriptionProvider defaultTypeProvider = TypeDescriptor.GetProvider(typeof(AClass));

    public AClassTypeProvider (): base(defaultTypeProvider)
    {

    }

    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
    {
        ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance);

        //returns a custom type descriptor based on a UserPropertyHostType enum value, and the default descriptor
        return new InfCustomTypeDescriptor(UserPropertyHostType.SiteRegion, defaultDescriptor);
    }
}


//type BClass Custom Provider
class BClassTypeProvider : TypeDescriptionProvider
{
    private static TypeDescriptionProvider defaultTypeProvider =   TypeDescriptor.GetProvider(typeof(BClass));

    public BClassTypeProvider (): base(defaultTypeProvider)
    {

    }

    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
    {
        ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance);

        //returns a custom type descriptor based on a UserPropertyHostType enum value, and the default descriptor
        return new InfCustomTypeDescriptor(UserPropertyHostType.Building, defaultDescriptor);
    }
}

Таким образом, каждый из моих пользовательских TypeDescriptionProviders вызывает базовый конструктор (родительский тип TypeDescriptionProvider) , передавая ему значение по умолчанию TypeDescriptionProvider определенного типа.

Метод GetTypeDescriptor () вызывает base.GetTypeDescriptor () , чтобы получить дескриптор по умолчанию, который затем используется моим дескриптором пользовательского типа для добавления пользовательских свойств.

Есть ли способ объединить их в единый универсальный пользовательский TypeDescriptionProvider , который имеет ту же функциональность, но не привязан к определенному типу? Могу ли я пропустить указание родительского TypeDescriptionProvider в конструкторе, но позже установить его в методе GetTypeDescriptor () , когда я точно знаю, какой тип объекта запрашивается? Или есть какой-то другой способ получить дескриптор по умолчанию для типа, отличного от вызова base.GetTypeDescriptor (Type t, object ins) метод?

Ответы [ 2 ]

2 голосов
/ 06 октября 2009

В прошлом я занимался этим с помощью универсального типа:

public class MyTypeDescriptionProvider<T> : TypeDescriptionProvider
{
  public MyTypeDescriptionProvider()
    : base(TypeDescriptor.GetProvider(typeof(T)))
  {
  }
}

Я почти уверен, что вы можете обработать его аналогичным образом в неуниверсальном типе, передав тип в качестве параметра конструктора:

public class MyTypeDescriptionProvider : TypeDescriptionProvider
{
  public MyTypeDescriptionProvider(Type t)
    : base(TypeDescriptor.GetProvider(t))
  {
  }
}

Это, вероятно, предпочтительнее, если вам не нужно использовать тип внутри провайдера - хотя еще не проверял его.

Тогда при использовании этого провайдера, классы регистрируются в соответствии с:

TypeDescriptor.AddProvider(new MyTypeDescriptionProvider<ClassA>(), typeof(ClassA));
TypeDescriptor.AddProvider(new MyTypeDescriptionProvider<ClassB>(), typeof(ClassB));

и т.д.

2 голосов
/ 06 октября 2009

Этот универсальный класс должен делать то, что вы хотите:

class CustomTypeProvider<T> : TypeDescriptionProvider
{
    private static TypeDescriptionProvider defaultTypeProvider = TypeDescriptor.GetProvider(typeof(T));

    public CustomTypeProvider(): base(defaultTypeProvider)
    {

    }

    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
    {
        ICustomTypeDescriptor defaultDescriptor = base.GetTypeDescriptor(objectType, instance);

        //returns a custom type descriptor based on a UserPropertyHostType enum value, and the default descriptor
        return new InfCustomTypeDescriptor(UserPropertyHostType.SiteRegion, defaultDescriptor);
    }
}
...