I'm currently mocking out an Interface with NSubstitute, which is basically a representation of a class with two properties and one method.
LoginViewModel = Substitute.For<ILoginViewModel>();
The mocked out interface is instantiated, then passed into a method which reflects upon it to get all the custom attributes.
LoginViewModel.Username = "User1";
LoginViewModel.Password = "Password1";
Each of the properties on the concrete implementation of the interface has a single custom attribute, however when reflected, the compiler shows no custom attributes.
[CustomRequired]
public string Username { get; set; }
[CustomRequired]
public string Password { get; set; }
Testing this without NSubstitute works. My question is: Does NSubstitute strip out Custom Attributes? Or is there a way to allow them through?
I don't know too much about custom attributes, so it is worth double checking the information in my answer.
First, NSubstitute does strip out some specific attributes, but not attributes in general. (Aside: NSubstitute uses Castle DynamicProxy to generate the proxy types, so to be more accurate NSubstitute asks Castle DP to strip these out. :) )
Secondly, if the attributes are declared on an interface they will not flow on to the class. They will however be available via the interface type itself. They will also be available if declared on a class and on substitutes for that class (provided the attribute is not configured explicitly to prevent being inherited):
public class MyAttribute : Attribute { }
public interface IHaveAttributes {
[My] string Sample { get; set; }
}
public class HaveAttributes : IHaveAttributes {
[My] public virtual string Sample { get; set; }
}
public class NoAttributes : IHaveAttributes {
public virtual string Sample { get; set; }
}
[Test]
public void TestAttributes()
{
// WORKS for class:
var sub = Substitute.For<HaveAttributes>();
var sampleProp = sub.GetType().GetProperty("Sample");
var attributes = Attribute.GetCustomAttributes(sampleProp, typeof(MyAttribute));
Assert.AreEqual(1, attributes.Length);
// WORKS directly from interface:
var sampleInterfaceProp = typeof(IHaveAttributes).GetProperty("Sample");
var attributes2 = Attribute.GetCustomAttributes(sampleInterfaceProp, typeof(MyAttribute));
Assert.AreEqual(1, attributes2.Length);
// Does NOT go from interface through to class (even non-substitutes):
var no = new NoAttributes();
var sampleProp2 = no.GetType().GetProperty("Sample");
var noAttributes = Attribute.GetCustomAttributes(sampleProp2, typeof(MyAttribute));
Assert.IsEmpty(noAttributes);
}
Related
Getting an error when trying to retrieve objects from mongodb:
InvalidOperationException: Can't compile a NewExpression with a
constructor declared on an abstract class
My class is:
public class App
{
public List<Feature> Features { get; set; }
}
public abstract class Feature
{
public string Name { get; set; }
}
public class ConcreteFeature : Feature
{
public string ConcreteProp { get; set; }
}
Not sure why it is having issues with abstractions. I see, mongodb recorded _t: "ConcreteFeature" type name, it has everything to deserialize it. I have no constructor in abstract class.
Ideas?
I needed to list "KnownTypes" for BsonClassMap to make it work:
BsonClassMap.RegisterClassMap<Feature>(cm => {
cm.AutoMap();
cm.SetIsRootClass(true);
var featureType = typeof(Feature);
featureType.Assembly.GetTypes()
.Where(type => featureType.IsAssignableFrom(type)).ToList()
.ForEach(type => cm.AddKnownType(type));
});
This way you won't need to touch the code even if you add new types as long as they are in 1 assembly. More info here.
1.On Abstract class Use
[BsonDiscriminator(Required = true)]
[BsonKnownTypes(typeof(ConcreteFeature)]
public abstract class Feature
{
public string Name { get; set; }
}
public class ConcreteFeature : Feature
{
public string ConcreteProp { get; set; }
}
You're never going to store your abstract class directly in the database. The whole known types stuff is just if you need the inheritance tree in the type discriminator which is typically overkill. The serializer does need to know about your concrete classes in advance though so the below will suffice.
BsonClassMap.RegisterClassMap<ConcreteFeature>();
Assuming you're going to be adding child classes regularly then you can use reflection and register them that way.
I have two classes, RichString and RequiredRichString. In RequiredRichString, I'm re-implementing the Value property with the 'new' keyword. If I reflect the attributes on Value on RequiredRichString, I only get Required, but after testing posting markup multiple times, AllowHtml is still taking effect.
public class RichString
{
[AllowHtml]
public string Value { get; set; }
}
public class RequiredRichString : RichString
{
[Required]
new public string Value { get; set; }
}
In short: Why does ASP.NET still acknowledge the AllowHtml attribute when I re-implement the Value property with new?
If you have the flag set:
[AttributeUsage(Inherited=true)]
Then the attribute will be inherited.
But you can subclass the Attribute to your needs, ie MyAttribute(Enabled = true) in the base class and MyAttribute(Enabled = false) in the new implementation. For instance...
[AttributeUsage(Inherited=true, AllowMultiple=true, Inherited=true)]
public class MyAttribute : Attribute
{
public bool Enabled { get; set; }
public MyAttribute() { }
public void SomethingTheAttributeDoes()
{
if (this.Enabled) this._DoIt)();
}
}
public class MyObject
{
[MyAttribute(Enabled = true)]
public double SizeOfIndexFinger { get; set; }
}
public class ExtendedObject : MyObject
{
[MyAttribute(Enabled = false)]
public new double SizeOfIndexFinger { get; set; }
}
Note this answer: How to hide an inherited property in a class without modifying the inherited class (base class)? - it seems maybe you can achieve what you want by using method overriding rather than hiding.
I can understand why you would think otherwise for a new property, but my understanding is that new is about providing a new implementation, often in the form of a new storage mechanism (a new backing field for instance) rather than changing the visible interface of the subclass. Inherited=true is a promise that subclasses will inherit the Attribute. It makes sense or at least it could be argued that only a superseding Attribute should be able to break this promise.
I've created a custom attribute where I want to access the the declaring class of the custom attribute property.
For example:
public class Dec
{
[MyCustomAttribute]
public string Bar {get;set;}
}
Here I would like (in the the cass of MyCustomAttribute) to get the type of the declaring class (Dec).
Is this by any means possible?
EDIT: Thanks for the replies everyone. I learned something new today.
As I've written, attributes are instantiated only when you request them with type.GetCustomAttributes(), but at that time, you alread have the Type. The only thing you can do is:
[AttributeUsage(AttributeTargets.Property)]
public class MyCustomAttribute : Attribute
{
public void DoSomething(Type t)
{
}
}
public class Dec
{
[MyCustomAttribute]
public string Bar { get; set; }
}
// Start of usage example
Type type = typeof(Dec);
var attributes = type.GetCustomAttributes(true);
var myCustomAttributes = attributes.OfType<MyCustomAttribute>();
// Shorter (no need for the first var attributes line):
// var myCustomAttributes = Attribute.GetCustomAttributes(type, typeof(MyCustomAttribute), true);
foreach (MyCustomAttribute attr in myCustomAttributes)
{
attr.DoSomething(type);
}
so pass the type as a parameter.
No, it is not - except for by build-time tools like PostSharp, Roslyn, etc.
You need to find a different approach - perhaps passing a Type in as a constructor argument; or (more likely), but having whatever logic you want to be attribute-based be aware of the declaration context; i.e. assuming MyCustomAttribute has a Foo() method, make it Foo(Type declaringType) or similar.
This might also work:
class MyCustomAttribute : Attribute
{
public Type DeclaringType { get; set; }
}
public class Dec
{
[MyCustomAttribute(DeclaringType=typeof(Dec))]
public string Bar { get; set; }
}
We have a custom ConfigurationManager library that serializes/deserializes a config.json file into an ExpandoObject.
Would it be possible to create a custom attribute that overrides the Getter/Setter of these properties to abstract this ExpandoObject?
Ideally I would be able to use the Attribute like this:
[System.AttributeUsage(System.AttributeTargets.Property)]
class Configureable : System.Attribute
{
public string Default { get; set; }
public bool IsEncrypted { get; set; }
}
class Test
{
[Configureable(Default = "0",IsEncrypted = false)]
public string MyValue { get; set; }
}
When I set the value of the decorated property I want to auto-magically update the value of the ExpandoObject, which would then in turn force an update be written to my config.json file.
When I access the value of the decorated property I want the getter to actually return the value of the underlying ExpandoObject. I can do this by manually having the developer modify the getter/setter. I was wondering if I could also do this with code inside of the attribute.
Thank you!
I found http://doc.postsharp.net/location-interception
That seems to do exactly what I want.
[System.AttributeUsage(System.AttributeTargets.Property)]
[Serializable]
class Configureable : LocationInterceptionAspect
{
public string Default { get; set; }
public bool IsEncrypted { get; set; }
public override void OnGetValue(LocationInterceptionArgs args)
{
base.OnGetValue(args);
if (args.Value == null)
{
}
}
public override void OnSetValue(LocationInterceptionArgs args)
{
//base.OnSetValue(args);
}
}
class Test
{
[Configureable(Default = "0",IsEncrypted = false)]
public string MyValue { get; set; }
}
ExpandoObject is a dictionary with object syntax. It is useful only in simple scenarios. If you need complex logic, use DynamicObject intead. Override its TryGetMember and TrySetMember methods to replicate functionality of ExpandoObject, then customize logic of these methods in the way you want.
It's not clear what your requirements are though. If you have a class which holds properties, what is the point of having dynamic objects?
I have a lot of similar classes generated by svcutil from some external WSDL file. Any class has a Header property and string property which named class name + "1".
For instance, I have classes: SimpleRequest that has Header property and SimpleRequest1 property.
Another one is ComplexRequest that has Header property and ComplexRequest1 property.
So, I want to create a common interface for such classes. So, basically I can define something like that:
interface ISomeRequestClass {
string Header;
// here is some definition for `class name + "1"` properties...
}
Is it possible to define such member in interface?
Here is post edit goes...
Here is sample of generated class:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class SimpleRequest
{
public string Header;
[System.ServiceModel.MessageBodyMemberAttribute(Name="SimpleRequest", Namespace="data", Order=0)]
public SimpleRequestMsg SimpleRequest1;
public SimpleRequest()
{
}
public SimpleRequest(string Header, SimpleRequestMsg SimpleRequest1)
{
this.Header = Header;
this.SimpleRequest1 = SimpleRequest1;
}
}
POST EDIT 2
I changed definition of this annoying +1 property to represent real actual picture. It's all has different class types. So how can I pull it out to common interface?
POST EDIT 3
Here is coupled question that could bring more clarify.
EDIT (after seeing your code sample): Technically speaking, your code does not have a Header property, it has a Header field. This is an important difference, since you cannot specify fields in an interface. However, using the method described below, you can add properties to your classes that return the field values.
Is it possible to define such member in interface?
No, interface names cannot be dynamic. Anyway, such an interface would not be very useful. If you had an instance of class ISomeRequestClass, what name would you use to access that property?
You can, however, use explicit interface implementation:
interface ISomeRequestClass {
string Header { get; set; }
string ClassName1 { get; set; }
}
class SomeClass : ISomeRequestClass {
string Header { ... }
string SomeClass1 { ... }
// new: explicit interface implementation
string ISomeRequestClass.ClassName1 {
get { return SomeClass1; }
set { SomeClass1 = value; }
}
}
You could define your interface more generally:
interface ISomeRequestClass {
string HeaderProp {get; set;}
string Prop {get; set;}
}
And your concrete classes could be extended (in an extra code file) by mapping interface members to class fields like so:
public partial class SimpleRequest : ISomeRequestClass
{
public string HeaderProp
{
get
{
return Header;
}
set
{
Header = value;
}
}
public string Prop
{
get
{
return SimpleRequest1;
}
set
{
SimpleRequest1= value;
}
}
}
Putting aside for a moment the naming of your classes and properties.
If you're looking to create an interface with a property relevant to your specific +1 type, you have a couple of options.
Use a base class for your +1's
If both of your +1 classes inherit from the same base class you can use this in your interface definition:
public interface IFoo
{
[...]
PlusOneBaseType MyPlusOneObject{get;set;}
}
Create a generic property on your interface
This method allows you to specify the type for the +1 property as a generic parameter:
public interface IFoo<TPlusOneType>
{
[...]
TPlusOneType MyPlusOneObject{get;set;}
}
Which you might use like:
public class SimpleRequest : IFoo<SimpleRequest1>
{
[...]
}
Update
Given that your classes are partial classes, you could always create a second (non machine generated) version of the partial class that impliments your interface.
You mentioned svcutil so I assume you are using these classes as WCF DataContracts?
If that is the case then you could make use the name property of DataMemberAttribute.
interface IRequest
{
string Header { get; set; }
string Request1 { get; set; }
}
[DataContract]
class SimpleRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="SimpleRequest1"]
public string Request1 { get; set; }
}
[DataContract]
class ComplexRequest : IRequest
{
[DataMember]
public string Header { get; set; }
[DataMember(Name="ComplexRequest1"]
public string Request1 { get; set; }
}
If you are concerned giving yourself more work when you regenerate the code at some point in the future, then I recommend you write a PowerShell script to do this transformation automatically. After all svcutil is just a script written by some guy at Microsoft. It is not magic or "correct" or "standard". Your script can make a call to scvutil and then make a few quick changes to the resulting file.
EDIT (After seeing your edit)
You are already using MessageBodyMemberAttribute's Name property so just change this:
public string SimpleRequest1;
To
public string Request1;
Do you actually need these classes to have a common interface? I'd be tempted to instead create a wrapper interface (or just a concrete class) which could then use reflection to access the fields in question:
// TODO: Make this class implement an appropriate new interface if you want
// to, for mocking purposes.
public sealed class RequestWrapper<TRequest, TMessage>
{
private static readonly FieldInfo headerField;
private static readonly FieldInfo messageField;
static RequestWrapper()
{
// TODO: Validation
headerField = typeof(TRequest).GetField("Header");
messageField = typeof(TRequest).GetField(typeof(TRequest).Name + "1");
}
private readonly TRequest;
public RequestWrapper(TRequest request)
{
this.request = request;
}
public string Header
{
get { return (string) headerField.GetValue(request); }
set { headerField.SetValue(request, value); }
}
public TMessage Message
{
get { return (TMessage) messageField.GetValue(request); }
get { messageField.SetValue(request, value); }
}
}
You could use expression trees to build delegates for this if the reflection proves too slow, but I'd stick to a simple solution to start with.
The advantage of this is that you only need to write this code once - but it does mean creating a wrapper around the real request objects, which the partial class answers don't.