Alright, so after a few hours of me playing around to no avail, I built a model:
[AttributeUsage(AttributeTargets.All)]
public class PublicAttribute : System.Attribute
{
public enum Access { Public, Private }
public PublicAttribute(string Name, Access acs)
{
}
public PublicAttribute(string Name, Access acs, Action get, Action set)
{
}
}
So that if somebody were to do something like this:
[Public("PublicProperty", PublicAttribute.Access.Public)]
private string PrivateProperty = "hello";
or
[Public("PublicProperty", PublicAttribute.Access.Public, ()=>{return PrivateProperty;}, ()=>{PrivateProperty = value})]
private string PrivateProperty = "hello";
and then if somebody was trying to access PrivateProperty, they could just go:
ContainingClass.PublicProperty = //ect
"PublicProperty". and that is because of the attribute, and it would use those get/set accessors.
What I'd like to know:
Is this even possible?
Is there something that already does this?
If its possible, (even if there is something else) How do i do this?
Basically no to all 3, as C# is a strongly typed language. Even with duck typing what you're trying to achieve doesn't fit the language.
The attributes you've written allow you to interrogate the properties that have those attributes in the class, but you still need to use Reflection to discover which properties of the attribute class are set. The syntax you want to use is checked at compile-time.
No, this is not possible using attributes. Properties are part of the class metadata emitted by the C# compiler, and the C# compiler does not consider custom attributes.
You may be able to do this by using a post-processor such as PostSharp, which can rewrite your assembly after the fact, and can be instructed to consider custom attributes. However, you still wouldn't be able to include a delegate in the attribute: the set of types that can be stored in attribute state is extremely limited.
Microsoft made the WebMethodAttribute in a way reminiscent of what you're trying to describe making it represent more permission than C# public, effectively making a method available outside the application domain to the entire Internet (a very global scope). You might read it to get real implementation insight and ideas.
But you're hitting it very simply. You'll have to program some infrastructure to make it work. It's not automatic and you don't have access to Microsoft's source code for all the details.
Related
i want use custom attribute on my n-tier project. for
-Caching-
-Logging
-Validation
-Exception
First of all you should search for AOP. this is some kind of developing methodology
Aspect-Oriented Programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. Wikipedia
It is not as simple as you think,in C# you have to use some 3rd party Library.
I suggest to start with MrAdvice, it will helps you.
Writing your custom attributes would look a little something like this:
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method)]
public class LogAttribute : Attribute
{
public bool _loggingEnabled;
public LogAttribute(loggingEnabled)
{
_loggingEnabled = loggingEnabled;
}
}
Usage example:
[Log(true)]
public class SampleClass
{
}
If you require further clarification if you share a little bit more about your intended usage of the attributes I'd be able to clarify a bit more. For instance, I'm not sure if you wanted your logging attribute to give you a means to explicitly state if that class/struct would be logged, but that's how I decided to demonstrate this. Also, note you can apply that to properties, and various other members via the AttributeUsage attribute on your attribute class declaration. I hope that helps.
Update:
Save method example:
[Log(true)]
public void Save(Company company)
{
_context.Save();
}
Then you'll use the static method Attribute.GetCustomAttribute(MemberInfo element, Type attributeType) to retrieve information stored in that attribute. Since in this case, you'll likely want to use logging in many places you'd write another method (most likely static as well) somewhere else in your application that'd look something like this (see the link to the System.Reflection reference below for more information).
public static void Log(MemberInfo element)
{
LogAttribute attribute = Attribute.GetCustomAttribute(element, typeof(LogAttribute);
if (attribute._loggingEnabled)
{
// Create log file and add information from here.
}
}
Attribute Reference
Reflection Reference
So I've got this boilerplate code that I want to apply to a bunch of properties of certain classes, that is essentially identical for each one. Rather than have to type this same code out again and again for all of these properties, I was wondering if there was any way I could dynamically build these property methods either post-compile or at runtime, by assigning a C# attribute to the property that includes the slight difference for each method (a string) and then finding these properties by reflection.
I'm aware of PostSharp, but I'm looking for something free or open source.
For example, instead of having to do this:
public string Name {
get { return _member.GetValue( "othername" ); }
set { _member.SetValue( "othername", value ); }
}
...for each property I have, I just want to say this:
[MapTo( "othername" )]
public string Name { get; set; }
Any thoughts?
You can use Mono.Cecil for dynamic code injection.
You can make these properties as virtual and generate class that overrides these properties and compile new class to assembly where overridden properties will be defined. Then you should create instance of dynamic generated class and used it as defined class.
You can do something similar using the Unity interception extension.
OK, so it probably merits its own answer. I am aware of the following AOP Frameworks for which you won't have to pay:
Castle Dynamic Proxy
Introducing LinFu, Code
Looks like you are looking for an AOP (Aspect Oriented Programming) like PostSharp.
It allows you to programatically inject code (just like you mentioned) and is very flexible.
Check out CInject on Codeplex which is an open-source alternative to code injection
I've created a simple Attribute:
[AttributeUsage(AttributeTargets.Method)]
public class InitAttribute : System.Attribute
{
public InitAttribute()
{
Console.WriteLine("Works!");
}
}
and I apply it to a simple method:
static class Logger
{
public static string _severity;
public static void Init(string severity)
{
_severity = severity;
}
[Init()]
public static void p()
{
Console.WriteLine(_severity);
}
}
What is going on is pretty streight-forward. Only, I expect the attribute to perform an action (printing Works!), but this does not happen.
Addictionally, printing "Works!" is of course just for debugging purposes: I'd like to access the instance's property _severity (to check if is != null, for example), but everything I keep reading about attributes (that are pretty new to me) is about accessing the class' methods or properties and so on via reflection. Once I've evaluated _severity, how can I modify the behavior of the decorated method (in this case, rise an exception "Logger is not initialized" and do not execute it)?
Any help appreciated.
If you need to perform an action as control enters a method, you should look at aspect-oriented programming and frameworks such as PostSharp. Attributes are not designed to perform anything by themselves. They are just a bunch of data (or metadata if you will) attached to stuff in IL assemblies that can be queried at runtime.
Attributes only allow decoration of types and members, but the attribute itself cannot acces the decorated object. You will have to use the constructor parameters of the attribute to pass in any data you require to work with within the attribute.
If you wish to use attributes to automatically alter the behaviour of their target objects, you will have to look at AOP solutions like PostSharp.
The attribute is never actually instantiated and so its constructor is never called. The attribute remains as meta-data until you use reflection to retrieve it. As has been mentioned previously what you are after is an Aspect Oriented Programming tool. PostSharp works by altering the assembly as a post-build step. If you are using the Castle Windsor or Unity Inversion of Control Containers they both offer AOP capabilities as well.
Is there a good way to allow only a certain class to have read/write access to properties in another class without having inheritance structure between them during design mode in .NET?
So if a class has public properties, only a certain class has visibility to these properties?
If not possible during design mode, then during run time. I know of a hokey way using flags in set and get statements but I think there are better ways.
There is no friend access in C#. You have public/protected/internal (including [InternalsVisibleTo]), but nothing more granular (i.e. at the inter-type level). So, no.
You can implement this using the internal keyword in C#:
The internal keyword is an access
modifier for types and type members.
Internal types or members are
accessible only within files in the
same assembly, as in this example:
public class BaseClass
{
// Only accessible within the same assembly
internal static int x = 0;
}
See also: Practical usings of “internal” keyword in C#
If you make the properties public anyone can access them. If you make them internal, protected, or even private --- anyone can still access them using reflection. If you want to discourage their use, use internal like Mitch suggested.
If there is a security reason for having this constraint, use Code Access Security to protect your properties. Note that this isn't something simple you can throw together -- thought must be put into your security model and the permissions you expose. Also realize that this must be done on an assembly level and will affect deployment of your application.
Chances are you probably don't need to do something so deep. You can probably "discourage" people from accessing those properties by hiding them behind an explicitly-implemented interface.
There's something I want to customize in the System.Web.Script.Services.ScriptHandlerFactory and other .NET stuff inside an internal class. Unfortunately, it's an internal class. What options do I have when trying to customize a method in this class?
You might find this recent article enlightening. Basically, it says that you can't override anything marked internal, and the source is about as authoritative as it gets. Best you can hope for is an extension method.
The internal keyword signifies that a unit of code (class, method, etc.) is "public" to the assembly it is in, but private to any other assembly.
Because you are not in the same assembly, you cannot do anything. If it wasn't internal you could use the new keyword on the method you're overriding (to hide the original implementation) when extending the class.
In short: you are to be SOL.
The only thing i can think of you could do is write a proxy class, where one of your private fields is the class you'd want to extend and you implement all it's methods and proxy their calls. that way you can still customize output, but you'd have to get your class used, and considering it's marked internal, i'm not sure that's possible without some serious hacking.
using System;
...
using System.Web.Script.Services
namespace MyGreatCompany.ScriptServices
{
public class MyScriptHandlerFactory /* implement all the interfaces */
{
private ScriptHandlerFactory internalFactory;
public MyScriptHandlerFactory()
{
internalFactory = new ScriptHandlerFactory();
}
...
}
}
This could make what you want to accomplish possible, but it won't be pretty.
I believe you can use Reflection to get around the access modifiers on a class, so perhaps you can use Reflection.Emit to generate a type that inherits from an internal type (but NOT the sealed modifier), though I can't find an example of this online.
This certainly works for accessing private members of classes, and probably for inheritance of non-sealed classes. But it doesn't help much if the target methods are not already marked virtual.
It depends on the assembly. This could possibly violate some licensing (although its similar to some sort of static linking), and maybe even make deployment a nightmare, but you could consider:
Decompile and copy the code over to your own project; modify as needed
Recompile/patch the assembly and add an "InternalsVisibleToAttribute"