Johnny5
Johnny5

Reputation: 6862

Add an attribute to another assembly's class

Is it somehow possible to extend a type, wich is defined in another assembly, to add an attribute on one of its properties?

Exemple I have in assembly FooBar:

public class Foo
{
   public string Bar { get; set; }
}

But in my UI assembly, I want to pass this type to a third party tool, and for this third party tool to work correctly I need the Bar property to have a specific attribute. This attribute is defined in the third party assembly, and I don't want a reference to this assembly in my FooBar assembly, since FooBar contains my domain an this is a UI tool.

Upvotes: 7

Views: 9161

Answers (4)

Jordão
Jordão

Reputation: 56477

What I think you need is some kind of adapter layer that will not let that infrastructure dependency leak into your domain logic. Maybe you can create an adapter class that will be like a data transfer object to the other technology. This class lives in an integration assembly that has a dependency on the 3rd party library:

public class FooDTO {
   [TheirAttribute]
   public string Bar { get; set; }
}

You can then use something like AutoMapper to ease the pain of changing representations.

The ideal solution, though, is if the 3rd party library supported additional ways to provide metadata about their operations. Maybe you can ask them for this feature.

Upvotes: 0

João Angelo
João Angelo

Reputation: 57688

You can't, if the thirdy-party tool uses standard reflection to get the attributes for your type.

You can, if the third-party tool uses the TypeDescriptor API to get the attributes for your type.

Sample code for the type descriptor case:

public class Foo
{
    public string Bar { get; set; }
}

class FooMetadata
{
    [Display(Name = "Bar")]
    public string Bar { get; set; }
}

static void Main(string[] args)
{
    PropertyDescriptorCollection properties;

    AssociatedMetadataTypeTypeDescriptionProvider typeDescriptionProvider;

    properties = TypeDescriptor.GetProperties(typeof(Foo));
    Console.WriteLine(properties[0].Attributes.Count); // Prints X

    typeDescriptionProvider = new AssociatedMetadataTypeTypeDescriptionProvider(
        typeof(Foo),
        typeof(FooMetadata));

    TypeDescriptor.AddProviderTransparent(typeDescriptionProvider, typeof(Foo));

    properties = TypeDescriptor.GetProperties(typeof(Foo));
    Console.WriteLine(properties[0].Attributes.Count); // Prints X+1
}

If you run this code you'll see that last console write prints plus one attribute because the Display attribute is now also being considered.

Upvotes: 10

Maess
Maess

Reputation: 4146

What about:

public class Foo
{
    public virtual string Bar
}

public class MyFoo : Foo
{
     [yourcustomattribute]
     public overrides string Bar
}

Upvotes: 0

Justin Niessner
Justin Niessner

Reputation: 245429

No. It's not possible to add attributes to types from separate assemblies.

What you can do, though, is create your own type that wraps the third-party type. Since you have full control over your wrapper class, you can add the attributes there.

Upvotes: 1

Related Questions