Add an attribute to another assembly's class - c#

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.

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.

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.

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

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.

Related

Alternative way(s) of structuring these objects in C# language

My goal is something along these lines:
// Defines members, for the "change-log" of the API,
// if the interface has changed, the API has a new major version.
// For "automatically generating changelogs" (for major versions) of the API
interface IApp
{
static string Name { get; set; }
}
// Internal class, not for usage outside of the dll
internal static class AppConfig
{
internal static bool IsPublished;
}
// Public available members from the API
public static class App : AppConfig, IApp
{
public static string Name { get; set; }
}
Now, there are a few wrongs in the structure above, based on C# language:
The interface cannot have static members
The class App is static, so it cannot inherit a static class
The AppConfig is static, so it cannot be inherited from
The class App is static, so it cannot have an interface
My current "solution":
public static partial class App
{
internal static bool IsPublished;
}
public static partial class App
{
public static string Name { get; set; }
}
Which I wanted to add contracts/interfaces to... So, I would maybe end up with something along these lines, "wrapping" APP:
public static class App
{
private static _App app;
static App()
{
app = new _App();
}
public static string Name { get { return app.Name; } }
}
internal interface _IApp
{
string Name { get; set; }
}
internal class _App : _AppConfig, _IApp
{
public string Name { get; set; }
}
internal class _AppConfig
{
internal static bool IsPublished;
}
This is long, tedious and boring. Three places to update insert a new member: Interface, _App-class (implementation) and in the static App-class (for API-users).
I want to achieve two things: A contract, interface, which defines all major changes from one version to another (read interfaces, print to change-log).
Making things that shall not be used for users of the API private (internal...).
The question? Anyone done something similar before, how did you solve it? Or talk me into forgetting the idea of a changelog based on interfaces... Because interfaces requires non-static objects, while I want static objects (at least on this particular object, it is static!).
PS: Atm. I read all public objects/members of the API to a log, which is now the "changelog". But starting on a new API, wanted to do something... different. :)
Edit: Note; I care about how the object looks on the "other side", it is an important thing. User of the API, to call App-members, shall be as simple as this (straight forward):
System.Windows.App.Name;
Which means the "outer class" (or however you want to look at it), is a static object.
Last note: I have several (12-15) objects of this "type", so I wanted a elegant structure, for all objects, all named similarly, so if you get to know one object, you know them all. Meaning: if one object has an interface, all others has one too. If one object is named "AppConfig", you can bet your life on that the other object also has a class named "OtherConfig". :)
It sounds like you're trying to have different "flavors" of the same class. Each one shares some common functionality? If so, I would use an abstract class as the base instead of an interface. Then, derive the other classes from that one. Unlike an interface, the abstract class will allow you to provide implementations at the parent level (e.g.: saving the object to disk or database). You can read more here: https://msdn.microsoft.com/en-us/library/sf985hc5.aspx.
I also agree with Filkolev, this doesn't sound like something that you would want a static class for.

Specify Implemented Interface as an Attribute in C#

I'm looking for anyone that can identify if this is possible or not, I am currently writing a small but extensible application that will have a plugin architecture.
To ensure the application is applicably to the current application, I'm using a custom Attribute to attach to the assembly
[AttributeUsage(AttributeTargets.Assembly)]
class PluginAttributes: Attribute
{
public PluginAttributes(string name, string description, string version, string author)
{
Name = name;
Description = description;
Version = version;
Author = author;
}
public string Name { get; private set; }
public string Description { get; private set; }
public string Version { get; private set; }
public string Author { get; private set; }
public XXXXXX Implements { get; private set; }
}
What I aiming for, is that the 'Implements' property will identify the appropriate plugin's Interface type. I have numerous interfaces defined in the library, such as ICompress, IEncrypt, ILogging, etc.
The attribute will be used to classify which type of plugin it is, without having to create a separate attribute for each.
I know I could have it passed as a string and use reflection, or use an enum, but I want the code to be as low-maintenance as possible, so that plugins can be developed without touching the core of the application.
I have made various of this type of plugin mechanism, and often it is easier to create an instance of the plugin class and check against various interfaces than to define it on a attribute or so. This will leave the door open for a plugin to implement more than one interface, which is nice.
You can do that like this using reflection (assuming you know the type name):
object plugin = Activator.CreateInstance("Assembly.Name", "Type.Class.Name");
if (plugin is ILogging)
{ ... }
if (plugin is IEncrypt)
{ ... }
For your current code, I suggest you to make the type of your Implements property Type and fill it using typeof(ILogging), typeof(IEncrypt), etc.

How to make readonly property in WCF? [duplicate]

I have a server side class which I make available on the client side through a [DataContract]. This class has a readonly field which I'd like to make available through a property. However, I'm unable to do so because it doesn't seem that I'm allowed to add a [DataMember] property without having both get and set.
So - is there a way to have a [DataMember] property without setter?
[DataContract]
class SomeClass
{
private readonly int _id;
public SomeClass() { .. }
[DataMember]
public int Id { get { return _id; } }
[DataMember]
public string SomeString { get; set; }
}
Or will the solution be use the [DataMember] as the field - (like e.g. shown here)? Tried doing this too, but it doesn't seem to care the field is readonly..?
Edit: Is the only way to make a readonly property by hacking it like this? (no - I don't want to do this...)
[DataMember]
public int Id
{
get { return _id; }
private set { /* NOOP */ }
}
Your "server-side" class won't be "made available" to the client, really.
What happens is this: based on the data contract, the client will create a new separate class from the XML schema of the service. It cannot use the server-side class per se!
It will re-create a new class from the XML schema definition, but that schema doesn't contain any of the .NET specific things like visibility or access modifiers - it's just a XML schema, after all. The client-side class will be created in such a way that it has the same "footprint" on the wire - e.g. it serializes into the same XML format, basically.
You cannot "transport" .NET specific know-how about the class through a standard SOAP-based service - after all, all you're passing around are serialized messages - no classes!
Check the "Four tenets of SOA" (defined by Don Box of Microsoft):
Boundaries are explicit
Services are autonomous
Services share schema and contract, not class
Compability is based upon policy
See point #3 - services share schema and contract, not class - you only ever share the interface and XML schema for the data contract - that's all - no .NET classes.
put DataMember attribute on a field not the property.
Remember thought, that WCF does not know encapsulation. Encapsulation is a OOP term, not a SOA term.
That said, remember that the field will be readonly for people using your class - anyone using the service will have full access to the field on their side.
I had some properties in a class in my service layer I wanted to pass over to Silverlight. I didn't want to create a whole new class.
Not really 'recommended', but this seemed the lesser of two evils to pass over the Total property to silverlight (solely for visual databinding).
public class PricingSummary
{
public int TotalItemCount { get; set; } // doesnt ideally belong here but used by top bar when out of store area
public decimal SubTotal { get; set; }
public decimal? Taxes { get; set; }
public decimal Discount { get; set; }
public decimal? ShippingTotal { get; set; }
public decimal Total
{
get
{
return + SubTotal
+ (ShippingTotal ?? 0)
+ (Taxes ?? 0)
- Discount;
}
set
{
throw new ApplicationException("Cannot be set");
}
}
}
There is a way to achieve this. But be warned that it directly violates the following principle cited in this answer:
"3. Services share schema and contract, not class."
If this violation does not concern you, this is what you do:
Move the service and data contracts into a separate (portable) class library. (Let's call this assembly SomeService.Contracts.) This is how you'd define an immutable [DataContract] class:
namespace SomeService.Contracts
{
[DataContract]
public sealed class Foo
{
public Foo(int x)
{
this.x = x;
}
public int X
{
get
{
return x;
}
}
[DataMember] // NB: applied to the backing field, not to the property!
private readonly int x;
}
}
Note that [DataMember] is applied to the backing field, and not to the corresponding read-only property.
Reference the contract assembly from both your service application project (I'll call mine SomeService.Web) and from your client projects (mine is called SomeService.Client). This might result in the following project dependencies inside your solution:
Next, when you add the service reference to your client project, make sure to have the option "reuse types" enabled, and ensure that your contract assembly (SomeService.Contracts) will be included in this:
VoilĂ ! Visual Studio, instead of generating a new Foo type from the service's WSDL schema, will reuse the immutable Foo type from your contract assembly.
One last warning: You've already strayed from the service principles cited in that other answer. But try not to stray any further. You might be tempted to start adding (business) logic to your data contract classes; don't. They should stay as close to dumb data transfer objects (DTOs) as you can manage.
Define the Service contract (Interface) Before implementing the contract using the class.

Understanding MEF System.Lazy<T,TMetaData>

I have been looking at the inner workings of the StockTrader RI for PRISM.
In this RI, MEF and a custom attribute system are used in combination to register views with regions as opposed to hooking up things to the RegionManager in the Module Initializer.
More specifically, there is a ViewExportAttribute which implements:
MetaDataAttribute
IViewRegionRegistration
The MetaDataAttribute and the "Attribute View" IViewRegionRegistration can be leveraged by System.Lazy<T,TMetaData> in AutoPopulateExportedViewsBehavior to achieve proper linking of regions and views.
In general the interplay between System.Lazy<T,TMetaData> and the actual metadata is elaborated here, more specifically the section "Using Strongly-typed Metadata".
To be clear, I understand the intent of Lazy and it clearly works. However, what I completely do not understand is where and how the link occurs between the metadata view supplied by the attribute (which is just an interface) and filling the TMetaData properties with the actual data supplied by the MetaDataAttribute.
To make my request even clearer, from the previously referenced example:
First, an interface is defined that can serve as a sort of template to pass certain metadata:
public interface IMessageSenderCapabilities
{
MessageTransport Transport { get; }
bool IsSecure { get; }
}
Next, A corresponding MetaDataAttribute is defined (which has the same properties as the previous interface)
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class MessageSenderAttribute : ExportAttribute
{
public MessageSenderAttribute() : base(typeof(IMessageSender)) { }
public MessageTransport Transport { get; set; }
public bool IsSecure { get; set; }
}
The attribute can be used in an export, where actual values are set for the attribute properties:
[MessageSender(Transport=MessageTransport.Smtp, IsSecure=true)]
public class SecureEmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine(message);
}
}
Now finally, we can do some importing:
public class HttpServerHealthMonitor
{
[ImportMany]
public Lazy<IMessageSender, IMessageSenderCapabilities>[] Senders { get; set; }
public void SendNotification()
{
foreach(var sender in Senders)
{
if (sender.Metadata.Transport == MessageTransport.Smtp &&
sender.Metadata.IsSecure)
{
var messageSender = sender.Value;
messageSender.Send("Server is fine");
break;
}
}
}
}
In this last step: sender.Metadata.Transport is evaluated on that very Lazy<>. Therefore, somewhere along the way, Lazy is made aware of the actual values of the metadata, not just the interface it gets passed. I want to understand how that happens, who or what is responsible for that. Even if it is just a very general flow.
After some more Reflector I think I can start to formulate an answer, although it turns out a lot of things are happening so this answer might evolve. I am writing it down hear for the benefit of learning this myself.
MEFBootsrapper.Run()
...
MEFBootstrapper.Container.GetExports(...) because CompositionContainer : ExportProvider, ... and ExportProvider defines public Lazy<T, TMetadataView> GetExport<T, TMetadataView>().
Next private Lazy<T, TMetadataView> GetExportCore<T, TMetadataView>(string contractName)
Next internal static Lazy<T, M> CreateStronglyTypedLazyOfTM<T, M>(Export export)
In here, AttributedModelServices.GetMetadataView<M>(export.Metadata) where M is the type of the MetaDataView. Whereas export is itself of type System.ComponentModel.Composition.Primitives.Export and this has a field ExportDefenition of which an inherited AttributedExportDefenition exists.
AttributedExportDefenition.MetaData whose getter contains this._member.TryExportMetadataForMember(out strs);
TryExportMetadataForMember(...) finally has a check type.IsAttributeDefined<MetadataAttributeAttribute> to see if there is a MetadataAttribute applied such as for MessageSenderAttribute in the question.
So this is more or less (very roughly) how we get to the actual metadata on the export and so probably with some more detours these exported metadata will also reach the Lazy although I am still to find out how that would work exactly.
Any feedback would still be appreciated.
Trying to understand what is going on with the code in my original question has spawned another question:
There is a subtle difference between the StockTrader RI and the example provided in the MEF Documentation
In Stocktrader, ViewExportAttribute is defined:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[MetadataAttribute]
public sealed class ViewExportAttribute : ExportAttribute, IViewRegionRegistration
{
... omitted for brevity ...
}
The MEF docs give a similar example (also in the original question):
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class MessageSenderAttribute : ExportAttribute
{
public MessageSenderAttribute() : base(typeof(IMessageSender)) { }
public MessageTransport Transport { get; set; }
public bool IsSecure { get; set; }
}
So with the above code blocks, the difference is that in the first case, the attribute derives from the Interface that defines the "metadata view" whereas in the second example, this is not the case; The attribute just has the same properties as the IMessageSenderCapabilities interface.
"No big deal" you would think but then in StockTrader RI:
[ImportMany(AllowRecomposition = true)]
public Lazy<object, IViewRegionRegistration>[] RegisteredViews { get; set; }
Whereas in the MEF Example:
[ImportMany]
public Lazy<IMessageSender, IMessageSenderCapabilities>[] Senders { get; set; }
So here, the difference is that in Stocktrader RI, the type that we are trying to Lazily import is not specified (it is just object) whereas in the second it is defined more specifically (IMessageSender).
The end result is more or less the same, some type is Lazily imported along with metadata.
However, what I would like to also learn is:
If the differences at the individual key points in both examples are related.
Specifically in the stock trader example, how do we know what to import as Lazy? Is it because the ViewExportAttribute specifically derives from IViewRegionRegistration that we can have Lazy<object, ... later on, i.e. that the system knows what to import because only types with that metadata will be imported? All this without specifying that object will actually be views, i.e. UserControls?

How to extract a superclass to encapsulate common code?

I have an application which uses plugins. After creating several of them I've found that a big chunk of code is repeated here and there on them so I want to extract a super "plugin base".
Previous the refactor I had the following structure:
After the refactor I have the next one:
I currently don't find a way to model the fact that the plugin engine has a property settings of type plugin settings and the plugin engine base has a property settings of type plugin settings base. I feel that somehow should be a way to declare that the settings property of the plugin engine base should be a "cast" of the settings property of the plugin engine and to model the fact that they both are the same property.
I'm not sure if the problem is explained enough. Feel free to ask for clarifications.
Thanks.
You can use generics. Create generic base class and specify generic parameter constraint to be of type PluginSettingsBase.
abstract class PluginEngineBase<T>
where T: PluginSettingsBase
{
public abstract T Settings { get; set; }
}
Inherit from base class parametrized by PluginsSettings class (thus it is inherited from PluginSettingsBase)
class PluginEngine : PluginEngineBase<PluginsSettings>
{
public PluginSettings Settings { get; set; }
}
Same with PluginData.
An approach I found:
Base class:
class PluginEngineBase
{
public PluginSettingsBase Settings { get; set; }
}
Inheritor:
class PluginEngine : PluginEngineBase
{
public PluginSettings Settings
{
get
{
return (PluginSettings)base.Settings;
}
set
{
base.Settings = value;
}
}
}

Categories

Resources