So I have a very simple class with one string as property. This string has to have a certain pattern. I'm trying to enforce this using code contracts. The class looks something like this:
class SimpleClass
{
public Property { get; set; }
public SimpleClass(string prop)
{
Contract.Requires(IsValid(prop));
this.Property = prop;
}
[ContractInvariantMethod]
void ObjectInvariant()
{
Contract.Invariant(IsValid(Property));
}
bool IsValid(string arg)
{
// Use regex to check if arg is a valid string
}
}
Very straightforward. However, this throws an unreadable exception and another one saying that 'Member SimpleClass.IsValid has less visibility than the enclosing method SimpleClass.#ctor(System.String)'. Why is this illegal? Should I copy/paste the regex into both methods? That seems to be the opposite of right. Please help me understand!
Another way is avoid 'primitive obsession' and use a class tailored to your purpose, e.g.:
public SimpleClass(Email address)
{
// no need to check, it must be valid :)
}
... and then encapsulate all your validation logic in the Email class. You'll still have the "string format" issues about validation, but I think a better idiom for this is to create a method called Email.TryParse, and fashion it along the lines of int.TryParse.
Just mark IsValid as public and you'll be fine. All "components" of a public surface contract have to be public as well, otherwise there is no way for a caller to check that the contract is satisfied.
#AI-CII I understand that, but that would be a design flaw as well, exposing implementation details to consumers.
A contract on a public method is not an implementation detail. A Contract.Requires says "hey, I require this to be true for me to do some work for you." If "this" isn't visible to the caller, how can the caller verify that the contract is satisfied?
You aren't exposing the implementation details of the method IsValid, you are only exposing what must be satisfied for the callee to do its job.
As Jason already stated, Code Contracts requires the method to be public as you already figured out yourself thanks to the exception message.
I understand however that simply making it public doesn't feel right. Perhaps the regex condition can be encapsulated to a static global function of a helper class?
E.g. If it were to check whether a string is a valid URL.
UrlHelper.IsValidUrl( string url )
This interested me so I started doing some googling. There is a solution! Although I would still prefer the helper class with the static method where possible.
It is called Code Contract Abbreviators. You need to include the sourcefile to your project yourself however.
Related
Thanks for looking!
Background
I have an extension method that is used to wrap a given method in a try/catch and I am adding code for logging any caught exceptions:
public static T HandleServerError<T>(this Func<T> func)
{
T result = default(T);
try
{
result = func();
}
catch (Exception ex)
{
//******************************
//Code for logging will go here.
//******************************
ErrorHandlers.ThrowServerErrorException(ex);
}
return result;
}
Here is how the method is called:
var result = new Func<SomeClass.SomeType>(() => SomeClass.SomeMethod(id, name, color, quantity)).HandleServerError();
return result;
As you can see, whatever method I am calling is injected into the extension method and executed inside the try/catch.
We will be using NLog or ELMAH for logging, but that is largely irrelevant to this question.
Problem
If something goes wrong, I need to log as much information about the delegated method as possible since things like "Object reference not set to an instance of an object" is not in itself helpful.
I would like to log the class and name of the method being called as well as the parameters in the method signature along with their values. If possible, I would even like to log which line failed, and finally the actual stack trace.
I am guessing that I need to use reflection for this and maybe catch the binding flags somehow as the injected method executes but I am not entirely sure if that is the best approach or if it is even feasible.
Question
Using C#, how do I get the meta information (i.e. method name, class of origin, parameters, parameter values) about an injected/delegated method?
Thanks in advance.
It seems to me that there is a possibility for you to improve the way you are adding this logging cross-cutting concern to your application.
The main issue here is that although your solution prevents you from making any changes to SomeClass.SomeMethod (or any called method), you still need to make changes to the consuming code. In other words you are breaking the Open/closed principle, which tells us that it must be possible to make these kinds of changes without changing any existing code.
You might think I'm exaggerating, but you probably already have over a hundred calls to HandleServerError in your application, and the number of calls will only be growing. And you'll soon add even more of those 'functional decorators' to the system pretty soon. Did you ever think about doing any authorization checks, method argument validation, instrumentation, or audit trailing? And you must admit that doing new Func<T>(() => someCall).HandleServerError() just feels messy, doesn't it?
You can resolve all these problems, including the problem of your actual question, by introducing the right abstraction to the system.
First step is to promote the given method arguments into a Parameter Object:
public SomeMethodParameters
{
public int Id { get; set; }
public string Name { get; set; }
public Color Color { get; set; }
public decimal Quantity { get; set; }
public decimal Result { get; set; }
}
Instead of passing all the individual arguments into a method, we can pass them all together as one single object. What's the use of that, you may say? Read on.
Second step is to introduce a generic interface to hide the actual logic of the SomeClass.SomeMethod (or in fact any method) behind:
public interface IMethodHandler<TParameter>
{
void Handle(TParameter parameter);
}
For each (business) operation in the system, you can write an IMethodHandler<TParameter> implementation. In your case you could simply create an implementation that wraps the call to SomeClass.SomeMethod, like this:
public class SomeMethodHandler
: IMethodHandler<SomeMethodParameters>
{
void Handle(SomeMethodParameters parameter)
{
parameter.Result = SomeClass.SomeMethod(
parameter.id,
parameter.Name,
parameter.Color,
parameter.Quantity);
}
}
It might look a bit silly to do things like this, but it allows you to implement this design quickly, and move the logic of the static SomeClass.SomeMethod inside of the SomeMethodHandler.
Third step is let consumers depend on a IMethodHandler<SomeMethodParameters> interface, instead of letting them depend on some static method in the system (in your case again the SomeClass.SomeMethod). Think for a moment what the benefits are of depending on such abstraction.
One interesting result of this is that it makes it much easier to unit test the consumer. But perhaps you're not interested in unit testing. But you are interested in loosely coupling. When consumers depend on such abstraction instead of a real implementation (especially static methods), you can do all kinds of crazy things, such as adding cross-cutting concerns such as logging.
A nice way to do this is to wrap IMethodHandler<T> implementations with a decorator. Here is a decorator for your use case:
public class LoggingMethodHandlerDecorator<T>
: IMethodHandler<T>
{
private readonly IMethodHandler<T> handler;
public LoggingMethodHandlerDecorator(
IMethodHandler<T> handler)
{
this.handler = handler;
}
public void Handle(T parameters)
{
try
{
this.handler.Handle(parameters);
}
catch (Exception ex)
{
//******************************
//Code for logging will go here.
//******************************
ErrorHandlers.ThrowServerErrorException(ex);
throw;
}
}
}
See how the Handle method of this decorator contains the code of your original HandleServerError<T> method? It's in fact not that much different from what you were already doing, since the HandleServerError 'decorated' (or 'extended') the behavior of the original method with new behavior. But instead of using method calls now, we're using objects.
The nice thing about all this is, is that this single generic LoggingMethodHandlerDecorator<T> can be wrapped around every single IMethodHandler<T> implementation and can be used by every consumer. This way we can add cross-cutting concerns such as logging, etc, without both the consumer and the method to know about this. This is the Open/closed principle.
But there is something else really nice about this. Your initial question was about how to get the information about the method name and the parameters. Well, all this information is easily available now, because we've wrapped all arguments in an object instead of calling some custom method wrapped inside a Func delegate. We could implement the catch clause like this:
string messageInfo = string.Format("<{0}>{1}</{0}>",
parameters.GetType().Name, string.Join("",
from property in parameters.GetType().GetProperties()
where property.CanRead
select string.Format("<{0}>{1}</{0}>",
property.Name, property.GetValue(parameters, null)));
This serializes the name of the TParameter object with its values to an XML format. Or you can of course use .NET’s XmlSerializer to serialize the object to XML or use any other serialization you need. All the information if available in the metadata, which is quite nice. When you give the parameter object a good and unique name, it allows you to identify it in the log file right away. And together with the actual parameters and perhaps some context information (such as datetime, current user, etc) you will have all the information you need to fix a bug.
There is one difference between this LoggingMethodHandlerDecorator<T> and your original HandleServerError<T>, and that is the last throw statement. Your implementation implements some sort of ON ERROR RESUME NEXT which might not be the best thing to do. Is it actually safe to continue (and return the default value) when the method failed? In my experience it usually isn't, and continuing at this point, might make the developer writing the consuming class think that everything works as expected, or might even make the user of the application think that everything worked out as expected (that his changes were saved for instance, while in fact they weren't). There's usually not much you can do about this, and wrapping everything in catch statements only makes it worse, although I can imagine that you want to log this information. Don’t be fooled by user requirements such as “the application must always work” or “we don’t want to see any error pages”. Implementing those requirements by suppressing all errors will not help and will not fix the root cause. But nonetheless, if you really need to catch-and-continue, just remove the throw statement`, and you'll be back at the original behavior.
If you want to read more about this way of designing your system: start here.
You can simply access its Method and Target properties as it's basically any other delegate.
Just use func.Method and func.Target.
I have an interface IKey which I want to have a method which will return the key as a string. We looked at having a method like this:
String GetAsString();
which would return the string representation, but would have liked to be able to declare ToString() again in the interface to force implementers to implement it, but it doesn't force them to as they have an implementation inherited from Object. This was suggested:
public interface IKey
{
string ToString(string dummyParameter=null);
}
this forces an implementation of the method in any implementing class, but due to the way that optional parameters work callers do not need to provide a value for this, and you ensure that any calls to the ToString() method on objects which are either cast as the interface IKey or the implementing class will always call the class implementation and not the Object implementation.
In the implementations we can just ignore the dummyParameter and return what we want, safe in the knowledge that calling ToString() will always actually call ToString(null).
Now this feels wrong all over to me, but at the same time it does have something quite nice about it. It is almost exactly the same as having a method GetAsString() as this could only be called on the IKey interface and derived classes except that it looks like the more natural ToString() method that we want to use and that we are able to force the implementing of in the child class.
Having said that the dummy parameter which is not used feels wrong.
So is this horrendous? Or great?
And is this question appropriate for SO or should it be on Programmers?
Examples
public class Key :IKey
{
public string ToString(string abc = null)
{
return "100";
}
}
Key key = new Key ();
Trace.WriteLine (key.ToString());
Trace.WriteLine (key.ToString(null));
Trace.WriteLine (key.ToString("ac"));
Trace.WriteLine (((object)key).ToString());
output:
100
100
100
Blah.Tests.Key
It sounds like you're using an interface where you should be using an abstract class. The class below explicitly requires descendants to have implemented ToString.
abstract class X
{
public abstract override string ToString();
}
From my point of view such ToString() method in a custom interface slightly messed up things because a custom interface exposed a method with standard and well known name ToString().
I prefer something more straightforward and obvious like:
string KeyText { get; }
OR method
string ConvertKeyToString();
Another answer already suggests the abstract class, which I think is the best option for this.
The idea of adding a ToString with a default parameter to the interface doesn't work too well in practive. The overload resolution will find the ToString without parameters when called without parameters (which, I must say, seems intuitive). Consider the output of this program:
void Main()
{
Console.WriteLine(new Key().ToString());
}
public interface IKey
{
string ToString(string dummy = null);
}
class Key : IKey
{
public string ToString(string dummy)
{
return "myspecialKey";
}
}
This outputs the object.ToString() implementation. Therefore, if you are restricted to use an interface, I would name the method something else than ToString().
Re-purposing
(IMO) -ToString() already has a very well-defined purpose and meaning. It may be convenient for you to hijack it based on the name, but by saying it's required you're re-purposing something that you shouldn't.
The answer is to have your own separate method, the initial idea. Anything else means all the .NET documentation about ToString() becomes 'wrong'.
E.g. the Tag property being an object on many UI controls. It could be that you want to 'tag' controls in some kind of control gallery. Just because the name fits, and the type fits, doesn't mean the meaning is the same and you can grab hold of it and re-purpose it.
Naming
I would also suggest considering changing your interface name; unless the implementers are actually keys? I get the impression that they are simply 'keyed', or have some key associated with them. In which case, IKeyed, IIndexed or something might be better. Then a string Key { get; } becomes more attractive. Perhaps it's just the naming that's the issue here.?
I would call this abuse, because of the problem you hint at right here:
...and you ensure that any calls to the ToString() method on objects which are either cast as the interface IKey or the implementing class will always call the class implementation and not the Object implementation.
Consider the following code:
IKey someKey = ...;
string keyAsString = someKey.ToString();
object someKeyAsObject = (object)someKey;
string keyAsString2 = someKeyAsObject.ToString();
Anybody looking at this code would assume that keyAsString and keyAsString2 are the same. However, these would be calling different methods that may have different behavior. Eek!
Horrendous, if I have to pick just one word... Confused and suspicious would more accurately describe my reaction if I came across this in the wild.
I try to follow one rule above all others when designing API's: Do not surprise the developer.
This would most certainly be a surprise. It precludes the use of the expected output and usage of ToString() without special effort. The fact that there's no indication of the special effort required would be the "surprise" bit. The default implementation of ToString() ends up getting used more often than I would have expected. I would avoid prohibiting or distorting its usage unless I had no other reasonable way to solve an issue.
I don't think this would be "more natural" than a well named method/property that isn't already a member of object.
Just came across this. What about having the interface inherit IFormattable?
http://msdn.microsoft.com/en-us/library/system.iformattable.aspx
I haven't done this myself so I might be wrong, but that seems to enable use of a format parameter for a ToString method for your interface. Note you are still not alterring the parameterless ToString, which I agree with others should not be done in an interface, but instead you make use of ToString(string format, IFormatProvider provider) with a recognizable format input that basically means "give me a description of this object in the context that it implements IWhatever". Obviously each implemented classes will need to code the method, but that is only proper.
let's say i have this
public class MyClass
{
public string myMessage { get; set; }
void MyMethod()
{
string myMessage;
}
}
shouldn't i get an alert about myMessage in MyMethod hiding(?) the myMessage property on the class? i'm not getting anything to this effect when i build. how do i activate this check?
The problem here is that we have no way of distinguishing between a valid, desired case of hiding and an accidental case of hiding. We try to reserve warnings for situations where (1) the code is almost certainly wrong and (2) there is a straightforward way to rewrite the code so that the warning is eliminated if the code as stated is in fact desired.
This is often a desired case because of this:
class Frog
{
private string name;
public Frog(string name)
{
this.name = name;
You don't want to change the field "name" to something else because it is perfectly descriptive as-is. You don't want to change the parameter "name" to something else because you want to be able to do new Frog(name: "Kermit") in C# 4 or Visual Basic. Since the hiding is desired and the code is correct we don't want to produce a warning for the hiding.
I know of no warning for this condition. Within MyMethod(), you can use this.myMessage to disambiguate between the local and the class property.
Just FYI, properties are usually TitleCased while locals are camelCased. Using that convention can prevent naming clashes like the one you list.
Check out Lexical Scoping. The myMessage inside MyMethod is defined in a new scope. Any reference to myMessage within that method will assume you are referring to the variable defined in that scope. You can access the myMessage defined in MyClass by using this.myMessage.
EDIT:
Given that info, you can see why this is perfectly valid from the compiler's perspective. Whether or not it should give you a warning is interesting. As Mitch Wheat pointed out in his comment, a tool like ReSharper will warn you about these things, but it's debatable if a compiler should warn you about collisions for something which it handles with lexical scoping. Seems like more of a job for a complementary tool.
This is actually in accordance with one naming pattern for private fields, though I prefer _fieldName myself:
public class MyClass
{
private string myMessage;
public MyClass(string myMessage)
{
this.myMessage = myMessage;
}
}
I would like to be able to keep a C# API the same as it is now, but simply deprecate one of the parameters in a method call. Is it possible to do so, or do I need to create a new method without the parameter and mark the original one as Obsolete?
Short answer:
You will need to create a new nethod with the new signature, and mark the current as obsolete.
Longer answer
What you want to avoid at all cost is a code break! Then, particularly in a company framework, you want to advertise that your method will no longer be supported, for example, but you do not want to be responsible for depending solutions to crash because of an architecture or design decision or your side, right?
The ObsoleteAttribute class will do the trick for you.
Once a class member marked as obsolete, a warning will be raised on the client-side, the ones who use your framework, to continue that way, or even one of your colleague under the same project.
public class MyClass {
[Obsolete("This method should no longer be used, please use MyNewMethod() instead.")]
public void MyMethod(string name, long phoneNumber, long faxNumber) {
}
public void MyNewMethod(string name, long phoneNumber, long faxNumber, string email) {
}
}
This will advertise that MyMethod is no longer supported throughout your code users.
After a certain period of time, reasonable enough to allow everyone to change his/her code, you may tell this attribute to throw an error message when your obsolete method is still used in the code.
public class MyClass {
[Obsolete("This method should no longer be used, please use MyNewMethod() instead.", true)]
public void MyMethod(string name, long phoneNumber, long faxNumber) {
}
public void MyNewMethod(string name, long phoneNumber, long faxNumber, string email) {
}
}
By setting the second ObsoleteAttribute class constructor parameter to true, you tel the compiler to advertise the use of this method as an error.
After some time only, you can completely remove your method from your code to clean it up a little. This is part of the refactoring methods encouraged by the Agile Software Development methodology.
Does this help?
Yes, I think the only way is to create a new method without the parameter and mark the original one with ObsoleteAttribute.
With the Obsolete attribute:
[Obsolete("Please use void AnotherMethod() instead", false)]
void SomeMethod(Int32 data){
}
The Boolean in the attribute tells the compiler to generate a warning, if you change it to true the compiler will generate an error. See here for the documentation on it.
Yes. You can only mark types and members of types as obsolete, not individual parameters. You could, however, overload the method, thereby keeping the same name and mark the old one as obsolete:
class Act
{
[Obsolete("DoSomething(int, int) is obsolete", false /*warn only*/)]
public void DoSomething(int i, int j)
{
}
public void DoSomething(int i)
{
}
}
I think it would be best to create a new method.
What do you mean by making the parameter obsolete? Does this depend on a specific value for that argument? When you call a method, you always have to specify the argument anyway.
What I am looking for is a way to call a method after another method has been invoked but before it is entered. Example:
public class Test {
public void Tracer ( ... )
{
}
public int SomeFunction( string str )
{
return 0;
}
public void TestFun()
{
SomeFunction( "" );
}
}
In the example above I would like to have Tracer() called after SomeFunction() has been invoked by TestFun() but before SomeFunction() is entered. I'd also like to get reflection data on SomeFunction().
I found something interesting in everyone's answers. The best answer to the question is to use Castle's DynamicProxy; however, this is not that I'm going to use to solve my problem because it requires adding a library to my project. I have only a few methods that I need to "trace" so I've chosen to go with a modified "core" methodology mixed with the way Dynamic Proxy is implemented. I explain this in my answer to my own question below.
Just as a note I'm going to be looking into AOP and the ContextBoundObject class for some other applications.
You can use a dynamic proxy (Castle's DynamicProxy for example) to intercept the call, run whatever code you wish, and then either invoke your method or not, depending on your needs.
Use a *Core method:
public int SomeFunction(string str)
{
Tracer();
return SomeFunctionCore(str);
}
private int SomeFunctionCore(string str)
{
return 0;
}
A number of the .NET APIs use this (lots do in WPF).
Use delegates!
delegate void SomeFunctionDelegate(string s);
void Start()
{
TraceAndThenCallMethod(SomeFunction, "hoho");
}
void SomeFunction(string str)
{
//Do stuff with str
}
void TraceAndThenCallMethod(SomeFunctionDelegate sfd, string parameter)
{
Trace();
sfd(parameter);
}
You want to look into Aspect Oriented Programming. Here's a page I found for AOP in .NET: http://www.postsharp.org/aop.net/
Aspect Oriented Programming involves separating out "crosscutting concerns" from code. One example of this is logging - logging exists (hopefully) across all of your code. Should these methods all really need to know about logging? Maybe not. AOP is the study of separating these concerns from the code they deal with, and injecting them back in, either at compile-time or run-time. The link I posted contains links to several tools that can be used for both compile-time and run-time AOP.
.NET has a class called ContextBoundObject that you can use to setup message sinks to do call interception as long as you don't mind deriving from a base class this will give you what you are looking for without taking an library dependency.
You would have to use some form of AOP framework like SpringFramework.NET to do that.
If you need to do this on large scale (i.e. for every function in a program) and you don't want to hugely alter the source, you might look into using the .NET Profiling API. Its a little hairy to use since you have to build free-threaded COM objects to do so, but it gives you an enormous amount of control over the execution of the program.
This is the solution I've choosen to solve my problem. Since there is no automatic (attribute like) way to make this work I feel it is the least obtrusive and allows the functionality to be turned on and off by choosing what class get instantiated. Please note that this is not the best answer to my question but it is the better answer for my particular situation.
What's going on is that we're simply deriving a second class that sometimes or always be instantiated in place of its parent. The methods that we want to trace (or otherwise track) are declared virtual and reimplemented in the derived class to perform whatever actions we want to trace and then the function is called in the parent class.
public class TestClass {
public virtual void int SomeFunction( string /*str*/ )
{
return 0;
}
public void TestFun()
{
SomeFunction( "" );
}
}
public class TestClassTracer : TestClass {
public override void int SomeFunction( string str )
{
// do something
return base.SomeFunction( str );
}
}