I am looking for a way to specify a lets call it Decision Tree or a Flow.
I have a Start value 1 or REQUESTED and this enum can have multiple following values like 2 or IN_PROGRESS or 3 or DECLINED.
And now only from the value 2 it should be possible to go to a higher value like 4 or FINISHED.
What is the most practically way to define the possible paths a process or flow can have?
What's practical is often what's easiest to read an understand. To that end I recommend being explicit about what which states can lead to which other states. The enum is just a list of possible values. Using the int values of the enum might seem more concise, but it's harder to read and can lead to other problems.
First, here's an enum and a simple class that changes from one state to another if that change is allowed. (I didn't cover every state.)
enum RequestState
{
Requested,
InProgress,
Declined,
Finished
}
public class Request
{
private RequestState _state = RequestState.Requested;
public void BeginWork()
{
if (_state == RequestState.Declined || _state == RequestState.Finished)
throw new InvalidOperationException("You can only begin work on a new request.");
_state = RequestState.InProgress;
}
public void Decline()
{
if (_state == RequestState.Finished)
throw new InvalidOperationException("Too late - it's finished!");
_state = RequestState.Declined;
}
// etc.
}
If we base it on the numeric value of _state and determine that the number can only go up, a few things can go wrong:
Someone can rearrange the enums or add a new one, not knowing that the numeric value or position has logical significance. That's an easy mistake because that value usually isn't significant.
You might need to implement logic that isn't quite so simple. You might need a state that can be preceded by some of the values before it but not all of them.
You might realize that there's a valid reason for going backwards. What if a request is declined, and in the future you determine that you want to reopen requests, effectively sending them back to Requested?
If the way this is implemented starts out a little bit weird, those changes could make it even harder to change and follow. But if you just describe clearly what changes are possible given any state then it will be easy to read and modify.
You could do something to leverage that enums are basically just integers:
private static Status NextState(Status status)
{
var intOfStatus = ((int)status) + 1;
return (Status)intOfStatus;
}
And some sample logic based on this approach:
public enum Status
{
NotStarted = 0,
Started = 1,
InProgress = 2,
Declined = 3
}
public static void Main()
{
var curStatus = Status.NotStarted;
Console.WriteLine(curStatus.ToString()); //writes 'NotStarted'
if ((int)curStatus++ == (int)Status.Started)
{
curStatus = Status.Started;
}
Console.WriteLine(NextState(curStatus)); //writes 'InProgress'
}
I'm completely stuck with this for about 2 days now and it seems I simply can't get my head around the problem I'm facing.
Currently, I'm writing an SDP parsing library that should also be usable for creating correct SDP messages according to it's specification (https://www.rfc-editor.org/rfc/rfc4566). But the specification is sometimes very open or unclear, so I try to implement a necessary amount of flexibility while still being as close to the RFC as possible.
Example Problem
A SDP message can contain media information ("m" field) where as this information has the following pattern:
m=<media> <port> <proto> <fmt> ...
And example message could look like this:
m=video 49170/2 RTP/AVP 31
Take a look at the proto flag, which stands for Media Transport Protocol. According to the specification, this field can have the following values:
RTP/AVP
RTP/SAVP
UDP
This is a list of values, so it's obviously appropriate to take an enumeration.
public enum MediaTransportProtocolType {
RTP/AVP
RTP/SAVP
UDP
}
Ooops! But this doesn't work because of the "/" char. So, how am I able to use this for parsing? I extended the Enumeration fields with the DescriptionAttribute
public enum MediaTransportProtocolType {
[Description("RTP/AVP")
RTP_AVP
[Description("RTP/SAVP")
RTP_SAVP
[Description("UDP")
UDP
}
Now I can simply look up the appropriate media transport protocol type by it's description. But now, the RFC specification goes on:
This memo registers three values [...] If other RTP profiles are
defined in the future [...]
So it's possible that a future network device can send me an media transport protocol that I'm not aware of. The whole enumeration thing doesn't work here anymore as System.Enum is not extendable due to various reason.
Solution
On my way looking for a solution I met the Type Safe Enumeration Pattern (AKA StringEnum) as described in here: how can i use switch statement on type-safe enum pattern. This answer even describes a solution to make them switchable, even if it's an ugly solution IMHO.
But again, this does only work for a defined range. I extended the Type Safe Enumeration class with a dictionary to store instances that I can look up while parsing, but also add new ones if I don't now them.
But what about all the other fields? And what about casting?
This answer here describes an approach with a base class and casting through explicit operators: Casting string to type-safe-enum using user-defined conversion
I tried it out, but it's not working the way I'd like it to be. (Invalid casting exceptions, dirty two casts pattern, not extendable).
How does one parse SDP information correctly and easily while still providing a library that allows to create a correct SDP?
You can do something like this:
public sealed class MediaTransportProtocolType
{
public static readonly MediaTransportProtocolType RtpAvp =
new MediaTransportProtocolType("RTP/AVP");
public static readonly MediaTransportProtocolType RtpSavp =
new MediaTransportProtocolType("RTP/SAVP");
public static readonly MediaTransportProtocolType Udp =
new MediaTransportProtocolType("UDP");
public static readonly ReadOnlyCollection<MediaTransportProtocolType>
Values = new ReadOnlyCollection<MediaTransportProtocolType>(
new MediaTransportProtocolType[] { RtpAvp, RtpSavp, Udp });
private MediaTransportProtocolType(string name)
{
this.Name = name;
}
public string Name { get; private set; }
public static MediaTransportProtocolType Parse(string value)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException("value");
}
var comparer = StringComparer.OrdinalIgnoreCase;
if (comparer.Equals(value, RtpAvp.Name))
{
return RtpAvp;
}
else if (comparer.Equals(value, RtpSavp.Name))
{
return RtpSavp;
}
else if (comparer.Equals(value, Udp.Name))
{
return Udp;
}
else if (value.StartsWith("RTP/", StringComparison.OrdinalIgnoreCase))
{
// Normally we would throw an exception here, but future
// protocols are expected and we must be forward compatible.
return new MediaTransportProtocolType(name);
}
throw new FormatException(
"The value is not in an expected format. Value: " + value);
}
}
That allows you to use it as an enum like this:
var type = MediaTransportProtocolType.Udp;
And you can parse it:
var type = MediaTransportProtocolType.Parse(value);
And iterate over all known values:
foreach (var type in MediaTransportProtocolType.Values)
{
}
And parse returns a unknown/future protocol type as long as they start with "RTP/" (as defined by the specs).
Of course the question is, can your library handle 'unknown' protocols. If you can't, you shouldn't allow parsing them. You should throw an NotSupportedException and update the library when new protocols are added. Or if you want others to extend, you should allow others to define implementations that handle a specific protocol.
I'm developing scientific software that needs access to the periodic table of elements. An Element comprises of a set of Isotopes which have a few readonly properties (e.g. mass, abundance, atomic number, etc.). There are over 100 elements, and when factoring in their isotopes, there are well over 1000 isotopes. To populate all these objects at run time, I currently have an XML file (Build Action: Content)* containing all the elemental data that I parse in during the static constructor of the Element class:
public class Element {
private static readonly Dictionary<string, Element> _elements;
static Element()
{
_elements = new Dictionary<string, Element>();
LoadElements("Resources/Elements.xml"); // 461 KB file
}
static LoadElements(string resource) {
// code for construction of elements objects and population of the
// _elements dictionary.
}
private Element(blah) { \\ instance constructor }
}
This works, but there is a overhead in parsing in the file and I lose some flexibility in designing the Element class. The alternative is to hard-code each Isotope and Element into the static constructor. The advantage of the later is I would be able to add static readonly property for each Element (a useful feature):
public class Element {
private static readonly Dictionary<string, Element> _elements;
public static readonly Element Carbon = {get; private set;}
public static readonly Element Hydrogen = {get; private set;}
static Element()
{
_elements = new Dictionary<string, Element>();
Carbon = AddElement("Carbon", 6);
Carbon.AddIsotope(12, 12.0000000, 0.9893);
Carbon.AddIsotope(13, 13.0033548378, 0.0107);
Hydrogen = AddElement("Hydrogen", 1);
//Repeat this pattern for all the elements...
}
static Element AddElement(string name, double atomicNumber)
{
Element element = new Element(name, atomicNumber);
_elements.Add(name, element);
return element;
}
private Element(string name, double atomicNumber) {
// Not Important, just setting readonly properties
}
private void AddIsotope(int massNumber, double mass, double abundance) {
// Not Important;
}
}
However, this seems like a lot of hard-coded data to include in a class.cs file. So I am torn, on one hand it makes sense on a data management level to have the elemental data stored in an external file which is read in. But on the other hand, because all the data is really a bunch of constant/static readonly objects, this additional parsing work seems timely, unfruitful, and limits the API design. What is the correct way for creating all these objects?
*Note: the Build Action is set to Content for the case if the client wants to modify the values of the elements for whatever reason. This isn't a necessity and could be changed to an embedded resource.
I would consider putting the values in an embedded file, but possibly having an enum of the elements. (Probably not the isotopes, but provide an easy way of specifying an isotope from the elements.)
That way:
You can still have a strongly-typed API, and not rely on magic strings etc in user code
You can still make it easy to change the data later should you really wish to (and possibly supply a way of reading the data from an external source)
You probably make it easier to work with the data itself, as an XML file rather than C#
Don't worry about the parsing work - given that you only need to do it once, I find it hard to believe that it would be significant in terms of performance.
Check out the blue obelisk project which is hosted on sourceforge - I think you'll find some useful stuff there, possibly even exactly what you're looking for.
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?
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() { }
}