Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I know that attributes are extremely useful. There are some predefined ones such as [Browsable(false)] which allows you to hide properties in the properties tab. Here is a good question explaining attributes: What are attributes in .NET?
What are the predefined attributes (and their namespace) you actually use in your projects?
[DebuggerDisplay] can be really helpful to quickly see customized output of a Type when you mouse over the instance of the Type during debugging. example:
[DebuggerDisplay("FirstName={FirstName}, LastName={LastName}")]
class Customer
{
public string FirstName;
public string LastName;
}
This is how it should look in the debugger:
Also, it is worth mentioning that [WebMethod] attribute with CacheDuration property set can avoid unnecessary execution of the web service method.
System.Obsolete is one of the most useful attributes in the framework, in my opinion. The ability to raise a warning about code that should no longer be used is very useful. I love having a way to tell developers that something should no longer be used, as well as having a way to explain why and point to the better/new way of doing something.
The Conditional attribute is pretty handy too for debug usage. It allows you to add methods in your code for debug purposes that won't get compiled when you build your solution for release.
Then there are a lot of attributes specific to Web Controls that I find useful, but those are more specific and don't have any uses outside of the development of server controls from what I've found.
[Flags] is pretty handy. Syntactic sugar to be sure, but still rather nice.
[Flags]
enum SandwichStuff
{
Cheese = 1,
Pickles = 2,
Chips = 4,
Ham = 8,
Eggs = 16,
PeanutButter = 32,
Jam = 64
};
public Sandwich MakeSandwich(SandwichStuff stuff)
{
Console.WriteLine(stuff.ToString());
// ...
}
// ...
MakeSandwich(SandwichStuff.Cheese
| SandwichStuff.Ham
| SandwichStuff.PeanutButter);
// produces console output: "Cheese, Ham, PeanutButter"
Leppie points out something I hadn't realized, and which rather dampens my enthusiasm for this attribute: it does not instruct the compiler to allow bit combinations as valid values for enumeration variables, the compiler allows this for enumerations regardless. My C++ background showing through... sigh
I like [DebuggerStepThrough] from System.Diagnostics.
It's very handy for avoiding stepping into those one-line do-nothing methods or properties (if you're forced to work in an early .Net without automatic properties). Put the attribute on a short method or the getter or setter of a property, and you'll fly right by even when hitting "step into" in the debugger.
For what it's worth, here's a list of all .NET attributes. There are several hundred.
I don't know about anyone else but I have some serious RTFM to do!
My vote would be for Conditional
[Conditional("DEBUG")]
public void DebugOnlyFunction()
{
// your code here
}
You can use this to add a function with advanced debugging features; like Debug.Write, it is only called in debug builds, and so allows you to encapsulate complex debug logic outside the main flow of your program.
I always use the DisplayName, Description and DefaultValue attributes over public properties of my user controls, custom controls or any class I'll edit through a property grid. These tags are used by the .NET PropertyGrid to format the name, the description panel, and bolds values that are not set to the default values.
[DisplayName("Error color")]
[Description("The color used on nodes containing errors.")]
[DefaultValue(Color.Red)]
public Color ErrorColor
{
...
}
I just wish Visual Studio's IntelliSense would take the Description attribute into account if no XML comment are found. It would avoid having to repeat the same sentence twice.
[Serializable] is used all the time for serializing and deserializing objects to and from external data sources such as xml or from a remote server. More about it here.
In Hofstadtian spirit, the [Attribute] attribute is very useful, since it's how you create your own attributes. I've used attributes instead of interfaces to implement plugin systems, add descriptions to Enums, simulate multiple dispatch and other tricks.
Here is the post about interesting attribute InternalsVisibleTo. Basically what it does it mimics C++ friends access functionality. It comes very handy for unit testing.
I've found [DefaultValue] to be quite useful.
I'd suggest [TestFixture] and [Test] - from the nUnit library.
Unit tests in your code provide safety in refactoring and codified documentation.
[XmlIgnore]
as this allows you to ignore (in any xml serialisation) 'parent' objects that would otherwise cause exceptions when saving.
It's not well-named, not well-supported in the framework, and shouldn't require a parameter, but this attribute is a useful marker for immutable classes:
[ImmutableObject(true)]
I like using the [ThreadStatic] attribute in combination with thread and stack based programming. For example, if I want a value that I want to share with the rest of a call sequence, but I want to do it out of band (i.e. outside of the call parameters), I might employ something like this.
class MyContextInformation : IDisposable {
[ThreadStatic] private static MyContextInformation current;
public static MyContextInformation Current {
get { return current; }
}
private MyContextInformation previous;
public MyContextInformation(Object myData) {
this.myData = myData;
previous = current;
current = this;
}
public void Dispose() {
current = previous;
}
}
Later in my code, I can use this to provide contextual information out of band to people downstream from my code. Example:
using(new MyContextInformation(someInfoInContext)) {
...
}
The ThreadStatic attribute allows me to scope the call only to the thread in question avoiding the messy problem of data access across threads.
The DebuggerHiddenAttribute which allows to avoiding step into code which should not be debugged.
public static class CustomDebug
{
[DebuggerHidden]
public static void Assert(Boolean condition, Func<Exception> exceptionCreator) { ... }
}
...
// The following assert fails, and because of the attribute the exception is shown at this line
// Isn't affecting the stack trace
CustomDebug.Assert(false, () => new Exception());
Also it prevents from showing methods in stack trace, useful when having a method which just wraps another method:
[DebuggerHidden]
public Element GetElementAt(Vector2 position)
{
return GetElementAt(position.X, position.Y);
}
public Element GetElementAt(Single x, Single y) { ... }
If you now call GetElementAt(new Vector2(10, 10)) and a error occurs at the wrapped method, the call stack is not showing the method which is calling the method which throws the error.
DesignerSerializationVisibilityAttribute is very useful. When you put a runtime property on a control or component, and you don't want the designer to serialize it, you use it like this:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
get { return baz; }
set { baz = value; }
}
Only a few attributes get compiler support, but one very interesting use of attributes is in AOP: PostSharp uses your bespoke attributes to inject IL into methods, allowing all manner of abilities... log/trace being trivial examples - but some other good examples are things like automatic INotifyPropertyChanged implementation (here).
Some that occur and impact the compiler or runtime directly:
[Conditional("FOO")] - calls to this method (including argument evaluation) only occur if the "FOO" symbol is defined during build
[MethodImpl(...)] - used to indicate a few thing like synchronization, inlining
[PrincipalPermission(...)] - used to inject security checks into the code automatically
[TypeForwardedTo(...)] - used to move types between assemblies without rebuilding the callers
For things that are checked manually via reflection - I'm a big fan of the System.ComponentModel attributes; things like [TypeDescriptionProvider(...)], [TypeConverter(...)], and [Editor(...)] which can completely change the behavior of types in data-binding scenarios (i.e. dynamic properties etc).
If I were to do a code coverage crawl, I think these two would be top:
[Serializable]
[WebMethod]
I have been using the [DataObjectMethod] lately. It describes the method so you can use your class with the ObjectDataSource ( or other controls).
[DataObjectMethod(DataObjectMethodType.Select)]
[DataObjectMethod(DataObjectMethodType.Delete)]
[DataObjectMethod(DataObjectMethodType.Update)]
[DataObjectMethod(DataObjectMethodType.Insert)]
More info
In our current project, we use
[ComVisible(false)]
It controls accessibility of an individual managed type or member, or of all types within an assembly, to COM.
More Info
[TypeConverter(typeof(ExpandableObjectConverter))]
Tells the designer to expand the properties which are classes (of your control)
[Obfuscation]
Instructs obfuscation tools to take the specified actions for an assembly, type, or member. (Although typically you use an Assembly level [assembly:ObfuscateAssemblyAttribute(true)]
The attributes I use the most are the ones related to XML Serialization.
XmlRoot
XmlElement
XmlAttribute
etc...
Extremely useful when doing any quick and dirty XML parsing or serializing.
Being a middle tier developer I like
System.ComponentModel.EditorBrowsableAttribute Allows me to hide properties so that the UI developer is not overwhelmed with properties that they don't need to see.
System.ComponentModel.BindableAttribute Some things don't need to be databound. Again, lessens the work the UI developers need to do.
I also like the DefaultValue that Lawrence Johnston mentioned.
System.ComponentModel.BrowsableAttribute and the Flags are used regularly.
I use
System.STAThreadAttribute
System.ThreadStaticAttribute
when needed.
By the way. I these are just as valuable for all the .Net framework developers.
[EditorBrowsable(EditorBrowsableState.Never)] allows you to hide properties and methods from IntelliSense if the project is not in your solution. Very helpful for hiding invalid flows for fluent interfaces. How often do you want to GetHashCode() or Equals()?
For MVC [ActionName("Name")] allows you to have a Get action and Post action with the same method signature, or to use dashes in the action name, which otherwise would not be possible without creating a route for it.
I consider that is important to mention here that the following attributes are also very important:
STAThreadAttribute
Indicates that the COM threading model for an application is single-threaded apartment (STA).
For example this attribute is used in Windows Forms Applications:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
And also ...
SuppressMessageAttribute
Suppresses reporting of a specific static analysis tool rule violation, allowing multiple suppressions on a single code artifact.
For example:
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isChecked")]
[SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "fileIdentifier")]
static void FileNode(string name, bool isChecked)
{
string fileIdentifier = name;
string fileName = name;
string version = String.Empty;
}
Off the top of my head, here is a quick list, roughly sorted by frequency of use, of predefined attributes I actually use in a big project (~500k LoCs):
Flags, Serializable, WebMethod, COMVisible, TypeConverter, Conditional, ThreadStatic, Obsolete, InternalsVisibleTo, DebuggerStepThrough.
I generates data entity class via CodeSmith and I use attributes for some validation routine. Here is an example:
/// <summary>
/// Firm ID
/// </summary>
[ChineseDescription("送样单位编号")]
[ValidRequired()]
public string FirmGUID
{
get { return _firmGUID; }
set { _firmGUID = value; }
}
And I got an utility class to do the validation based on the attributes attached to the data entity class. Here is the code:
namespace Reform.Water.Business.Common
{
/// <summary>
/// Validation Utility
/// </summary>
public static class ValidationUtility
{
/// <summary>
/// Data entity validation
/// </summary>
/// <param name="data">Data entity object</param>
/// <returns>return true if the object is valid, otherwise return false</returns>
public static bool Validate(object data)
{
bool result = true;
PropertyInfo[] properties = data.GetType().GetProperties();
foreach (PropertyInfo p in properties)
{
//Length validatioin
Attribute attribute = Attribute.GetCustomAttribute(p,typeof(ValidLengthAttribute), false);
if (attribute != null)
{
ValidLengthAttribute validLengthAttribute = attribute as ValidLengthAttribute;
if (validLengthAttribute != null)
{
int maxLength = validLengthAttribute.MaxLength;
int minLength = validLengthAttribute.MinLength;
string stringValue = p.GetValue(data, null).ToString();
if (stringValue.Length < minLength || stringValue.Length > maxLength)
{
return false;
}
}
}
//Range validation
attribute = Attribute.GetCustomAttribute(p,typeof(ValidRangeAttribute), false);
if (attribute != null)
{
ValidRangeAttribute validRangeAttribute = attribute as ValidRangeAttribute;
if (validRangeAttribute != null)
{
decimal maxValue = decimal.MaxValue;
decimal minValue = decimal.MinValue;
decimal.TryParse(validRangeAttribute.MaxValueString, out maxValue);
decimal.TryParse(validRangeAttribute.MinValueString, out minValue);
decimal decimalValue = 0;
decimal.TryParse(p.GetValue(data, null).ToString(), out decimalValue);
if (decimalValue < minValue || decimalValue > maxValue)
{
return false;
}
}
}
//Regex validation
attribute = Attribute.GetCustomAttribute(p,typeof(ValidRegExAttribute), false);
if (attribute != null)
{
ValidRegExAttribute validRegExAttribute = attribute as ValidRegExAttribute;
if (validRegExAttribute != null)
{
string objectStringValue = p.GetValue(data, null).ToString();
string regExString = validRegExAttribute.RegExString;
Regex regEx = new Regex(regExString);
if (regEx.Match(objectStringValue) == null)
{
return false;
}
}
}
//Required field validation
attribute = Attribute.GetCustomAttribute(p,typeof(ValidRequiredAttribute), false);
if (attribute != null)
{
ValidRequiredAttribute validRequiredAttribute = attribute as ValidRequiredAttribute;
if (validRequiredAttribute != null)
{
object requiredPropertyValue = p.GetValue(data, null);
if (requiredPropertyValue == null || string.IsNullOrEmpty(requiredPropertyValue.ToString()))
{
return false;
}
}
}
}
return result;
}
}
}
[DeploymentItem("myFile1.txt")]
MSDN Doc on DeploymentItem
This is really useful if you are testing against a file or using the file as input to your test.
[System.Security.Permissions.PermissionSetAttribute] allows security actions for a PermissionSet to be applied to code using declarative security.
// usage:
public class FullConditionUITypeEditor : UITypeEditor
{
// The immediate caller is required to have been granted the FullTrust permission.
[PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
public FullConditionUITypeEditor() { }
}
Related
I'm trying to add custom coloring for only certain keywords in my Visual Studio editor for C# code. I want to be able to color any type that implements IDisposable as a different color. Ideally I'd like to create a simple list of classes/interfaces that derive from IDisposable in some sort of configuration that I can edit. (Although if you said there was a method/plugin that would automatically find all disposable types and color them independently that would be the Holy Grail).
I've done a ton of research and it looks like an "editor classifier" extension might do the trick. However I created one that merely tries to color the word "Stream" and although it does hit my code that attempts to highlight that word, it does not end up highlighted in the editor.
I have added my VS extension to Github here
This really seems like this should be fairly straightforward but I have gone down many alleys on this one only to find dead-ends. Is there a simpler way to do this, or is my extension broken?
Update
Very strange. I just ran my extension again and although it does not highlight the text in the editor it highlights all instances of "Stream" in the popup text when you hover over a type/variable! Is there any way to get it to apply to the editor?
Depending on wether you are using Jetbrains Resharper or not you may write a plugin for that. That way you are able not only to add visual notification of IDisposable on a variable but also provide quickfixes if, and only if, it is not beeing called, which is what i am assuming you want to catch. Mind you that i can imagine that there's already a R# plugin for that. I know i've considered this too, but i was too lazy to write a plugin for that.
Don't get me wrong btw - If you're not using r# yet you should consider trying it out.
Among others you'd be working with this: API-QuickFix
There are also ways to define custom keywords, as resharper does, given by a custom markup and apply quickfixes to that.
PS: No i don't work at jetbrains. it's just that good :)
UPDATE:
potential VS Extension fix?
check this one out: MSDN Link Highlighting Text
I tried opening your github project but couldn't so i thought i'll just check msdn instead. it seems you are deriving from the wrong class to fulfill your needs?
MSDN keyword "Editors - Extending the Editor - Walkthrough: Highlighting Text"
I know SO wants code on the site, but msdn links going down is rather unlikely and with the given information the content can be found easily enough :)
I'm a bit late to the party, but hey, why not throw my 2 cents in.
As you've explained in your question, your project has two basic parts:
Finding the classes that implement IDisposable
Highlighting them
The first is by far the hardest, though not impossible. A word-list based approach is probably the simplest, though it should be possible with Roslyn to figure out on the fly which classes inherit IDisposible.
You could also always resort to loading the project's compiled .exe/.dll in the background after a build and figuring out what the types are there, but you'd still have to write some magic glue code to figure out what short class names in the code referred to what actual full-name classes in the assembly.
The second part, highlighting, is quite easy once you know how to do it (it helps that I've spent the last several months working full-time on extending VS). Of course, with Visual Studio, nothing is as simple as it looks (despite the efforts of Microsoft to try to make it user-friendly). So, I've built a sample extension that highlights just classes named "Stream" within C# files to get you started.
The relevant code is below, and the full project source is on GitHub). It starts with a classification-tagger provider:
[Export(typeof(ITaggerProvider))]
[ContentType("CSharp")]
[TagType(typeof(ClassificationTag))]
[Name("HighlightDisposableTagger")]
public class HighlightDisposableTaggerProvider : ITaggerProvider
{
[Import]
private IClassificationTypeRegistryService _classificationRegistry = null;
[Import]
private IClassifierAggregatorService _classifierAggregator = null;
private bool _reentrant;
public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
{
if (_reentrant)
return null;
try {
_reentrant = true;
var classifier = _classifierAggregator.GetClassifier(buffer);
return new HighlightDisposableTagger(buffer, _classificationRegistry, classifier) as ITagger<T>;
}
finally {
_reentrant = false;
}
}
}
Then the tagger itself:
public class HighlightDisposableTagger : ITagger<ClassificationTag>
{
private const string DisposableFormatName = "HighlightDisposableFormat";
[Export]
[Name(DisposableFormatName)]
public static ClassificationTypeDefinition DisposableFormatType = null;
[Export(typeof(EditorFormatDefinition))]
[Name(DisposableFormatName)]
[ClassificationType(ClassificationTypeNames = DisposableFormatName)]
[UserVisible(true)]
public class DisposableFormatDefinition : ClassificationFormatDefinition
{
public DisposableFormatDefinition()
{
DisplayName = "Disposable Format";
ForegroundColor = Color.FromRgb(0xFF, 0x00, 0x00);
}
}
public event EventHandler<SnapshotSpanEventArgs> TagsChanged = delegate { };
private ITextBuffer _subjectBuffer;
private ClassificationTag _tag;
private IClassifier _classifier;
private bool _reentrant;
public HighlightDisposableTagger(ITextBuffer subjectBuffer, IClassificationTypeRegistryService typeService, IClassifier classifier)
{
_subjectBuffer = subjectBuffer;
var classificationType = typeService.GetClassificationType(DisposableFormatName);
_tag = new ClassificationTag(classificationType);
_classifier = classifier;
}
public IEnumerable<ITagSpan<ClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans)
{
if (_reentrant) {
return Enumerable.Empty<ITagSpan<ClassificationTag>>();
}
var tags = new List<ITagSpan<ClassificationTag>>();
try {
_reentrant = true;
foreach (var span in spans) {
if (span.IsEmpty)
continue;
foreach (var token in _classifier.GetClassificationSpans(span)) {
if (token.ClassificationType.IsOfType(/*PredefinedClassificationTypeNames.Identifier*/ "User Types")) {
// TODO: Somehow figure out if this refers to a class which implements IDisposable
if (token.Span.GetText() == "Stream") {
tags.Add(new TagSpan<ClassificationTag>(token.Span, _tag));
}
}
}
}
return tags;
}
finally {
_reentrant = false;
}
}
}
I've only tested this on VS2010, but it should work for VS2013 too (the only thing that might be different is the class classification name, but that's easy to discover with a well-placed breakpoint). I've never written an extension for VS2012, so I can't comment on that, but I know it's quite close to VS2013 in most respects.
So, one possible solution(I believe this one works):
1) Create your own content type which inherits from csharp.
2) Create new TextViewCreationListener which will swap out all "csharp" content types with your own one, thus potentially "disarming" all the other classifiers.
3) Register your classifier to handle your own content type.
Here is some of the code:
[Export(typeof(IVsTextViewCreationListener))]
[ContentType("csharp")]
[TextViewRole(PredefinedTextViewRoles.Editable)]
class TextViewCreationListener : IVsTextViewCreationListener {
internal readonly IVsEditorAdaptersFactoryService _adaptersFactory;
[Import] internal IContentTypeRegistryService ContentTypeRegistryService = null;
[ImportingConstructor]
public TextViewCreationListener(IVsEditorAdaptersFactoryService adaptersFactory) {
_adaptersFactory = adaptersFactory;
}
#region IVsTextViewCreationListener Members
public void VsTextViewCreated(VisualStudio.TextManager.Interop.IVsTextView textViewAdapter) {
var textView = _adaptersFactory.GetWpfTextView(textViewAdapter);
var myContent = ContentTypeRegistryService.GetContentType(MyContentType);
if(myContent == null)
{
ContentTypeRegistryService.AddContentType(MyContentType, new[] {"csharp"});
myContent = ContentTypeRegistryService.GetContentType(MyContentType);
}
// some kind of check if the content type is not already MyContentType.
textView.TextBuffer.ChangeContentType(myContent, null);
}
#endregion
}
And now, just modify your IClassifierProvider to register with your own content type, as such: [ContentType(MyContentType)]
Iin your own IClassifier, you can basically do your own calculation and once you think you can't handle the stuff, you could pass the control to other classifiers.
If you use MEF and import IClassifierAggregatorService, you can get a "MASTER-classifier" which will run all the logic for you. I haven't implemented it yet, but I've suggestes something similiar in the past, and it seemed to work. Alternatively you could maybe use [ImportMany] with List<IClassifier> and filter out the csharp ones?!
According to this answer when code uses local variables from inside lambda methods the compiler will generate extra classes that can have name such as c__DisplayClass1. For example the following (completely useless) code:
class Program
{
static void Main()
{
try {
implMain();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
static void implMain()
{
for (int i = 0; i < 10; i++) {
invoke(() => {
Console.WriteLine(i);
throw new InvalidOperationException();
});
}
}
static void invoke(Action what)
{
what();
}
}
outputs the following call stack:
System.InvalidOperationException
at ConsoleApplication1.Program.<>c__DisplayClass2.<implMain>b__0()
at ConsoleApplication1.Program.invoke(Action what)
at ConsoleApplication1.Program.implMain()
at ConsoleApplication1.Program.Main()
Note that there's c__DisplayClass2 in there which is a name of a class generated by the compiler to hold the loop variable.
According to this answer c__DisplayClass "means"
c --> anonymous method closure class ("DisplayClass")
Okay, but what does "DisplayClass" mean here?
What does this generated class "display"? In other words why is it not "MagicClass" or "GeneratedClass" or any other name?
From an answer to a related question by Eric Lippert:
The reason that a closure class is called "DisplayClass" is a bit unfortunate: this is jargon used by the debugger team to describe a class that has special behaviours when displayed in the debugger. Obviously we do not want to display "x" as a field of an impossibly-named class when you are debugging your code; rather, you want it to look like any other local variable. There is special gear in the debugger to handle doing so for this kind of display class. It probably should have been called "ClosureClass" instead, to make it easier to read disassembly.
You can get some insight from the C# compiler source as available from the SSCLI20 distribution, csharp/sccomp subdirectory. Searching the code for "display" gives most hits in the fncbind.cpp source code file. You'll see it used in code symbols as well as comments.
The comments strongly suggest that this was a term used internally by the team, possibly as far back as the design meetings. This is .NET 2.0 vintage code, there was not a lot of code rewriting going on yet. Just iterators and anonymous methods, both implemented in very similar ways. The term "display class" is offset from "user class" in the comments, a clear hint that they used the term to denote auto-generated classes. No strong hint why "display" was favored, I suspect that it might have something to do with these classes being visible in the metadata of the assembly.
Based on Reflector, DisplayClass can be translated as CompilerGeneratedClass
[CompilerGenerated]
private sealed class <>c__DisplayClass16b
{
// Fields
public MainForm <>4__this;
public object sender;
// Methods
public void <cmdADSInit_Click>b__16a()
{
ADS.Initialize();
this.<>4__this._Sender = this.sender;
this.<>4__this.SelectedObject = ADS.Instance;
}
}
Trying to manage access to a web site I created some necessary entities
The goal is use a custom permission attribute for some controller's action method of my MVC application.
[Permissions(PermissionType.SomePermissionName, CrudType.CanDelete)]
public ActionResult SomeAction()
{
}
For this operation I have two enums
[Flags]
public enum CrudType
{
CanCreate = 0x1,
CanRead = 0x2,
CanUpdate = 0x4,
CanDelete = 0x8,
}
[Flags]
public enum PermissionType
{
SomePermissionName = 0x1,
//...
}
Now I want the method below to check permissions
public static bool CanAccess(RolePermissions rp, CrudType crudType)
{
var pInfo = rp.GetType().GetProperties();
var res = pInfo.FirstOrDefault(x => x.Name == crudType.ToString());
if(res != null)
{
return Convert.ToBoolean(res.GetValue(rp, null));
}
return false;
}
It works good but is it safe to use reflection here? Is it a good style?
One more question is about such piece of code
var permission = PermissionService.GetByName(permissionType.ToString());
Here I'm trying to get a permission object from a database using some named constant from the PermissionType enum.
In both cases the correct work depends on relationships between enums and some table fields or records. On other side I have a good mechanism of controlling logic (as it seems to me).
Is that a good way?
ANOTHER EDIT
In your case it would make sense to create a readonly property ExistingPermissions for the RolePermissions class, and do the merging of the four booleans into one CrudType within that property getter. Then you can just do rp.ExistingPermissions.HasFlag(permissionToCheck).
EDITED
Thanks to #DevDelivery for pointing out the issue - good catch. Unfortunately the fixed solution isn't as pretty as I was hoping for, so in this case it might make sense to go with #DevDelivery's approach.
Since you have your CrudType as "bitfields", you can use a cleaner approach (less code and better readability):
public static bool CanAccess(RolePermissions rp, CrudType permissionToCheck)
{
CrudType existingPermissions =
SetPermissionFlag(CrudType.CanCreate, rp.CanCreate) |
SetPermissionFlag(CrudType.CanRead, rp.CanRead) |
SetPermissionFlag(CrudType.CanUpdate, rp.CanUpdate) |
SetPermissionFlag(CrudType.CanDelete, rp.CanDelete);
return existingPermissions.HasFlag(permissionToCheck);
}
public static CrudType SetPermissionFlag(CrudType crudType, bool permission)
{
return (CrudType)((int)crudType * Convert.ToInt32(permission));
}
The drawback compared to your solution is that you will have to modify this method in case you add more operations (to the existing CanRead, etc.).
Using reflection has a performance impact and the late-binding means that changing a name of a enum
or property will not get caught by the compiler.
Plus, this code is very hard to understand, thus difficult to maintain.
Here there are only 4 options to check. A simple switch statement is easier, faster, and cleaner.
Using reflection would make sense if you were trying to allow for changes to the database or for third-party components to introduce new permissions.
Maybe this is dreaming, but is it possible to create an attribute that caches the output of a function (say, in HttpRuntime.Cache) and returns the value from the cache instead of actually executing the function when the parameters to the function are the same?
When I say function, I'm talking about any function, whether it fetches data from a DB, whether it adds two integers, or whether it spits out the content of a file. Any function.
Your best bet is Postsharp. I have no idea if they have what you need, but that's certainly worth checking. By the way, make sure to publish the answer here if you find one.
EDIT: also, googling "postsharp caching" gives some links, like this one: Caching with C#, AOP and PostSharp
UPDATE: I recently stumbled upon this article: Introducing Attribute Based Caching. It describes a postsharp-based library on http://cache.codeplex.com/ if you are still looking for a solution.
I have just the same problem - I have multiply expensive methods in my app and it is necessary for me to cache those results. Some time ago I just copy-pasted similar code but then I decided to factor this logic out of my domain.
This is how I did it before:
static List<News> _topNews = null;
static DateTime _topNewsLastUpdateTime = DateTime.MinValue;
const int CacheTime = 5; // In minutes
public IList<News> GetTopNews()
{
if (_topNewsLastUpdateTime.AddMinutes(CacheTime) < DateTime.Now)
{
_topNews = GetList(TopNewsCount);
}
return _topNews;
}
And that is how I can write it now:
public IList<News> GetTopNews()
{
return Cacher.GetFromCache(() => GetList(TopNewsCount));
}
Cacher - is a simple helper class, here it is:
public static class Cacher
{
const int CacheTime = 5; // In minutes
static Dictionary<long, CacheItem> _cachedResults = new Dictionary<long, CacheItem>();
public static T GetFromCache<T>(Func<T> action)
{
long code = action.GetHashCode();
if (!_cachedResults.ContainsKey(code))
{
lock (_cachedResults)
{
if (!_cachedResults.ContainsKey(code))
{
_cachedResults.Add(code, new CacheItem { LastUpdateTime = DateTime.MinValue });
}
}
}
CacheItem item = _cachedResults[code];
if (item.LastUpdateTime.AddMinutes(CacheTime) >= DateTime.Now)
{
return (T)item.Result;
}
T result = action();
_cachedResults[code] = new CacheItem
{
LastUpdateTime = DateTime.Now,
Result = result
};
return result;
}
}
class CacheItem
{
public DateTime LastUpdateTime { get; set; }
public object Result { get; set; }
}
A few words about Cacher. You might notice that I don't use Monitor.Enter() ( lock(...) ) while computing results. It's because copying CacheItem pointer ( return (T)_cachedResults[code].Result; line) is thread safe operation - it is performed by only one stroke. Also it is ok if more than one thread will change this pointer at the same time - they all will be valid.
You could add a dictionary to your class using a comma separated string including the function name as the key, and the result as the value. Then when your functions can check the dictionary for the existence of that value. Save the dictionary in the cache so that it exists for all users.
PostSharp is your one stop shop for this if you want to create a [Cache] attribute (or similar) that you can stick on any method anywhere. Previously when I used PostSharp I could never get past how slow it made my builds (this was back in 2007ish, so this might not be relevant anymore).
An alternate solution is to look into using Render.Partial with ASP.NET MVC in combination with OutputCaching. This is a great solution for serving html for widgets / page regions.
Another solution that would be with MVC would be to implement your [Cache] attribute as an ActionFilterAttribute. This would allow you to take a controller method and tag it to be cached. It would only work for controller methods since the AOP magic only can occur with the ActionFilterAttributes during the MVC pipeline.
Implementing AOP through ActionFilterAttribute has evolved to be the goto solution for my shop.
AFAIK, frankly, no.
But this would be quite an undertaking to implement within the framework in order for it to work generically for everybody in all circumstances, anyway - you could, however, tailor something quite sufficient to needs by simply (where simplicity is relative to needs, obviously) using abstraction, inheritance and the existing ASP.NET Cache.
If you don't need attribute configuration but accept code configuration, maybe MbCache is what you're looking for?
I would like to implement what I know as a CVAR System, I'm not entirely sure on what the official name of it is (if any).
It's essentially a system used in some programs and video games, where a user can pull down a console and input a command, such as "variable 500" to set that variable to 500. Instances of this can be found in any Half-Life game, Doom and Quake games, and many more. The general idea seems to be to hide the underlying architecture, but still allow protected access, for instance, one may be able to view the value for, say, gravity, but not change it. Some of these values may also be functions, for instance, a user may be able to input "create " to create an enemy type at their location, or some other location specified.
Looking through the Half Life 2 SDK, and from what I remember on the GoldSrc SDK, it seems like they at least implemented "flagging" of sorts, where certain commands would only work under certain conditions, such as if another value was set, or if the user has some permission level.
My initial thought was to create a Dictionary, or an object similar to do that, and use that to bind string values to function delegates, as well as keep a "protection" level of sorts, to limit usage of certain commands. However, this seems rather cumbersome, as I believe I would have to go through and add in a new entry manually for each value or function I wanted to implement. I also don't know if this would give me the control level I'm looking for.
I believe ideally what I would like would be a CVAR System class, as well as a Register function that can take it say, a variable/function delegate, a string to access it, and whatever protection level I need. This way I can add what I need as I see them, so everything is still in it's related classes and files.
I'm really just looking for some ideas here, so my questions are:
Has anyone ever done something like this before, and if so, how?
Would my implementation work? (Theoretically, if not, can you think of a better way?)
If someone is more knowledgeable with how one of the previously mentioned titles does it, can you elaborate on that a bit? It seems to be hard to find documentation on them.
I'm not really looking for specific code, just more of structuring design. And it doesn't have to be "commercial" or work just like another, I just need something to get me going.
Were you thinking about something like this?
class CVAR
{
[ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
private float gravity = 0.1f;
[ProtectionLevel(CVARFlags.InGameOnly | CVARFlags.Admin)]
private float friction = 0.1f;
[ProtectionLevel(CVARFlags.ReadOnly)]
private string serverVersion = "x.x.x";
public void SetCVARValue(string commandLine) {
string cvarName = GetCvarName(commandLine); // parse the cmd line and get the cvar name from there
object cvarValue = GetCvarValue(commandLine); // parse the value from the string
FieldInfo field = typeof(CVAR).GetField(cvarName);
object[] attributes = field.GetCustomAttributes(typeof(ProtectionLevel), false);
if(attributes.Length > 0) {
ProtectionLevelAttribute attr = (ProtectionLevelAttribute)attributes[0];
if(attr.CheckConditions(World.Instance)) {
field.SetValue(this, cvarValue);
} else {
// error report
}
}
}
}
You could write a parser that looks for commands like
/object_property value
/object_method arg1 arg2
A dictionary, like you suggested, could map those strings to properties and functions. The creation of the dictionary could be done dynamically using reflection by looping through eligible objects, taking their public methods and accessors, and generating a string for them.
Then the dictionary could be mapped in a class for convenience and error checking.
For the methods, the dictionary values could be delegates that take 0..n arguments, for the properties/fields, you will need to be able to some data binding between your actual fields and the dictionary value. UNLESS, your objects themselves refer to the dictionaries for their values, in which case the values only live in place.
To do so, you could simply register your properties using reflection in the object constructor, then call the dictionary in your properties.
[Flags]
public enum CVarAccessibilities
{
Settable,
Gettable
}
public class CVar<T>
{
public CVarAccessibilities Accessibility { get; set; }
T val;
public T Value {
get { return val; }
set
{
if (!Accessibility.HasFlag(CVarAccessibilities.Settable))
return; // just don't set it, maybe print some warning
val = value;
}
}
}
public static class CVarRegistry
{
static Dictionary<string, Object> CVars;
static CVarRegistry { /* use reflections to initialize the dictionary */ }
public static T GetValue<T>(Type owner, string paramName)
{
CVar cvar;
if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
throw new MyCustomException();
return (T)cvar.Value;
}
public static void SetValue<T>(Type owner, string paramName, T value)
{
CVar cvar;
if (!CVars.TryGetValue(owner.Name + "_" + paramName, out cvar)
throw new MyCustomException();
cvar.Value = value;
}
}
public class MyObject
{
public static int MyRegisteredValue
{
get { return Global.CVarRegistry.GetValue<int>(typeof(MyObject), "MyRegisteredValue"); }
set { Global.CVarRegistry.SetValue(typeof(MyObject), "MyRegisteredValue"); }
}
}
Hope that helps!
This is more commonly known as 'tweak' variables.
Good discussion here: https://gamedev.stackexchange.com/questions/3631/tweaking-and-settings-runtime-variable-modification-and-persistence