I have a Web solution which contains two projects (A and B) with B referencing A.
In A I have an Html extension method that obviously can be called from either A or B.
My question is once the method is called (usually from a partial view) is there a way inside the method to figure out whether the call came from Assembly A or Assembly B without passing anything to it?
I tried to see if I can do anything with HttpContext.Current.Request but could not find anything useful. I can get the URI but that still does not tell me which assembly the file that originated the Request is in.
Thanks for your answers - the method returns a string and the string is from a string.resx file which I have one for each assembly. That is why I need to know which file to access to return the string. Since each assembly "registers" itself on start up if I add a new assembly my method will not change, since it will just look up the assembly.In fact my whole project will not change. The reason why I am not introducing another parameter at this time is b/c it will mean a HUGE amount of changes and I honestly don't see the benefit. While I see your point and I generally agree with it I think in my case it's not that the method returns different things , it's just grabbing the correct resource file based on the assembly.
As SLaks pointed out, you can check HttpContext.Current.Application.GetType().Assembly.
However I agree with John in the comments that you have probably made a bad design decision if you need this.
The Problem
Your method is a hypocrite.
It talks different to different callers but doesn't tell it in open.
You see, each method defines a certain contract with arguments and a return type.
For example, int.Parse says that it takes a string and turns it into an int. If we want to change default behavior, we may also give it NumberStyles and/or IFormatProvider.
We the consumers don't know how int.Parse is implemented. Because it is static, we most certainly expect it doesn't have side effects and will always return the same value for the same set of parameters.
Repeat this mantra after me:
Explicit is better than implicit.
You would probably be very angry if you found out int.Parse somehow analyzes your code and changes its behavior depending on where it's called from.
It's the caller's responsibility to define the context, not the callee's.
Try to give simple and concise answers to questions below:
What happens if the method is called from assembly C?
How would you unit-test it? What if some other developer uses this method in unit tests?
What happens if you rename assembly A or B? Merge them? Split them further?
Will you remember to change this method if anything above happens?
If answering any of the questions above clearly poses a challenge for you, it is a sign you're Doing It Wrong™.
Instead you should...
Introduce a Parameter
Think about the method contract. What can you do to make it full and descriptive?
Define a generic (as in English) method in a separate assembly that doesn't know anything about the callers and has additional parameters, and define parameter-filling shortcuts for it in concrete assemblies.
It's better that these parameters don't know anything about the assemblies either.
For example, if you needed to resolve URLs inside your method, you could accept string baseUrl or Func<string, string> urlResolver so it's potentially usable from any assembly that cares to specify those.
In the worst case, you could define an enum with possible caller contexts and pass it to the method. This will make your design problem explicit, rather than implicit. Obvious problem is always better than hidden problem, although worse than no problem at all.
Check HttpContext.Current.Application.GetType().Assembly
Related
As shown here, attribute constructors are not called until you reflect to get the attribute values. However, as you may also know, you can only pass compile-time constant values to attribute constructors. Why is this? I think many people would much prefer to do something like this:
[MyAttribute(new MyClass(foo, bar, baz, jQuery)]
than passing a string (causing stringly typed code too!) with those values, turned into strings, and then relying on Regex to try and get the value instead of just using the actual value, and instead of using compile-time warnings/errors depending on exceptions that might be thrown somewhere that has nothing to do with the class except that a method that it called uses some attributes that were typed wrong.
What limitation caused this?
Attributes are part of metadata. You need to be able to reflect on metadata in an assembly without running code in that assembly.
Imagine for example that you are writing a compiler that needs to read attributes from an assembly in order to compile some source code. Do you really want the code in the referenced assembly to be loaded and executed? Do you want to put a requirement on compiler writers that they write compilers that can run arbitrary code in referenced assemblies during the compilation? Code that might crash, or go into infinite loops, or contact databases that the developer doesn't have permission to talk to? The number of awful scenarios is huge and we eliminate all of them by requiring that attributes be dead simple.
The issue is with the constructor arguments. They need to come from somewhere, they are not supplied by code that consumes the attribute. They must be supplied by the Reflection plumbing when it creates the attribute object by calling its constructor. For which it needs the constructor argument values.
This starts at compile time with the compiler parsing the attribute and recording the constructor arguments. It stores those argument values in the assembly metadata in a binary format. At issue then is that the runtime needs a highly standardized way to deserialize those values, one that preferably doesn't depend on any of the .NET classes that you'd normally use the de/serialize data. Because there's no guarantee that such classes are actually available at runtime, they won't be in a very trimmed version of .NET like the Micro Framework.
Even something as common as binary serialization with the BinaryFormatter class is troublesome, note how it requires the [Serializable] attribute on the class to allow it to do its job. Versioning would also be an enormous problem, clearly such a serializer class could never change for the risk of breaking attributes in old assemblies.
This is a rock and a hard place, solved by the CLS designers by heavily restricting the allowed types for an attribute constructor. They didn't leave much, just the simple values types, string, a simple one-dimensional array of them and Type. Never a problem deserializing them since their binary representation is simple and unambiguous. Quite a restriction but attributes can still be pretty expressive. The ultimate fallback is to use a string and decode that string in the constructor at runtime. Creating an object of MyClass isn't an issue, you can do so in the attribute constructor. You'll have to encode the arguments that this constructor needs however as properties of the attribute.
The probably most correct answer as to why you can only use constants for attributes is because the C#/BCL design team did not judge supporting anything else important enough to be added (i.e. not worth the effort).
When you build, the C# compiler will instantiate the attributes you have placed in your code and serialize them, so that they can be stored in the generated assembly. It was probably more important to ensure that attributes can be retrieved quickly and reliably than it was to support more complex scenarios.
Also, code that fails because some attribute property value is wrong is much easier to debug than some framework-internal deserialization error. Consider what would happen if the class definition for MyClass was defined in an external assembly - you compile and embed one version, then update the class definition for MyClass and run your application: boom!
On the other hand, it's seriously frustrating that DateTime instances are not constants.
What limitation caused this?
The reason it isn't possible to do what you describe is probably not caused by any limitation, but it's purely a language design decision. Basically, when designing the language they said "this should be possible but not this". If they really wanted this to be possible, the "limitations" would have been dealt with and this would be possible. I don't know the specific reasoning behind this decision though.
/.../ passing a string (causing stringly typed code too!) with those values, turned into strings, and then relying on Regex to try and get the value instead of just using the actual value /.../
I have been in similar situations. I sometimes wanted to use attributes with lambda expressions to implement something in a functional way. But after all, c# is not a functional language, and if I wrote the code in a non-functional way I haven't had the need for such attributes.
In short, I think like this: If I want to develop this in a functional way, I should use a functional language like f#. Now I use c# and I do it in a non-functional way, and then I don't need such attributes.
Perhaps you should simply reconsider your design and not use the attributes like you currently do.
UPDATE 1:
I claimed c# is not a functional language, but that is a subjective view and there is no rigourous definition of "Functional Language". I agree with the Adam Wright, "/.../ As such, I wouldn't class C# as functional in general discussion - it is, at best, multi-paradigm, with some functional flavour." at Why is C# a functional programmming language?
UPDATE 2:
I found this post by Jon Skeet: https://stackoverflow.com/a/294259/1105687 It regards not allowing generic attribute types, but the reasoning could be similar in this case:
Answer from Eric Lippert (paraphrased): no particular reason, except
to avoid complexity in both the language and compiler for a use case
which doesn't add much value.
My resources are stored in an assembly of their own, and I have a reference to that assembly in my web app. I am able to access resources in two different ways - via compiled constants or by using a ResourceManager.
var method1 = Prototype.Localization.CustomerRecord.BillingId;
or
var resx = new ResourceManager(typeof (Prototype.Localization.CustomerRecord));
var method2 = resx.GetString("BillingId");
Using the first approach seems like a no brainer (but that generally means it's going to come back and bite me when things get more complicated), so what are the advantages or disadvantages to the second approach? Is the first approach going to cause me issues down the road?
So what are the advantages or disadvantages to the second approach?
2nd approach is what resx compiler does under the cover. IMO 2nd one is always worse because you have a string (then it may goes detached and you won't know until run-time) and because of that you'll lack of compile-time checks and design-time support.
Is the first approach going to cause me issues down the road?
No, at least no more than anything else (because you'll catch errors in your HTML pages when you'll first compile them at run-time).
So I may ask: if first approach is shorter and easier then is there any good reason to use the 2nd one? My answer is "no" (moreover you can mix them, in case you'll need it for a special thing).
Yeah, I agree with Adriano that the 2nd is worse because of those "Magic" strings.
The first approach you have some more advantages that would include compile time check, since you reference a class and a property if this property doesn't exist you will get an error back, intellisense is another one.
Another advantage, is that if you decided to move away from the built in resource manager, you could just replace the generated class (resource class) by your own respecting the namespace and so on, with your own internal logic.
IMO, I would stick with the first one.
I have a number of MethodBase instances referencing different open generic methods (expected), e.g. representing the following methods:
T Foo<T>(T nevermind, T other);
T Foo<T>(string nevermind, T other);
And I have a single MethodBase instance referencing closed method that was actually called (actual), e.g.:
int Foo<int>(string nevermind, int other);
How can I programatically check if actual closed method could match any of given expected open methods, especially when considering all the generics pitfalls and complications?
Specifically, I would like to identify that the correct item from expected list for given actual closed method is T Foo<T>(string nevermind, T other); and not the second one.
Moreover, for MethodBase corresponding to double Foo<double>(double something, string other) I'd like to have no results matched.
Is iterating through candidate methods and checking if each parameter from expected is assignable from corresponding actual parameter a good way? If so, is it the simplest way? Do I need to consider any special cases to not match methods that will not be chosen according to method overloads resolution rules in .NET?
Tl;dr. The problem is not possible to solve using reflection, at least as I understand it, and without more specificity..
Method resolution rules are extremely complicated, especially for generic methods. There are many pitfalls you will fall into. You will need to know not only the method, the type parameter, but also a lot of information about the target, along with its own type parameters. In some cases, where the method was called from.
Method has implementation in a base class but is hidden by the child.
Method is from an interface, and was implemented explicitly, and may have another method with the same name on the implementer.
A methods such as Foo<T>(T a, string other), Foo<T>(string a, T other), Foo<T>(string a, string other) and some other variations cannot be disambiguated for T = string unless you know where the call is coming from (these are legal methods, and the one that gets called depends on several things).
Generic constraints can be placed on methods.
Polymorphism on the argument types, including generic variance for interfaces and delegates.
Optional parameters.
This goes on and on.
Basically, it can never work. Not using reflection. Not the way you're proposing. Even if you have restrictions about what calls can be made, you'd have to decide which things to check and which not, and you will always miss a few. These aren't the only pitfalls by the way, just a random sampling.
However, you do have some options.
The first, and best option in my opinion, is going a step back and thinking about the original problem. Post that if you can. It might have a different answer, and people will be able to advise you better. Hopefully it's less complicated to understand.
If you limited the scope of the matter greatly, such as no generic constraints, no interfaces, and so forth, this might be possible. It would be error prone, because there are lots of gotcha's.
You can try resolving it at runtime using dynamic binding, but the way dynamic binding resolves methods may be different from the way it normally happens. I don't know much about this, though.
You can hook the runtime and also investigate method calls as they are resolved. There are libraries for this. This will even allow you to understand how late binding is resolved.
Finally, you can look into the IL, possibly with the aid of various tools and libraries such as Mono.Cecil. In the built library, method resolution has already been performed, so you will see exactly which methods are called from which locations. This doesn't sound feasible however.
Oh, there is Roslyn, and other compilers with interfaces. They already have the resolution logic implemented, so they may make the task easier. IF they are open source, you can try to understand how method resolution is performed there. I'm kind of out of my depth here, though. And I suspect it's not feasible.
I don't like posting links to specific libraries because I'd rather you just research them. Also because there are many options.
To summarize, at least in my opinion, and as I understand the problem, without great restrictions on the methods and more information, it is impossible.
With extension methods we can easily add methods to any type. Obviously this opens the possibility in a future version of .net the extension method could no longer get called (for example the type now includes a method with identical signature to the extension method).
Should this be a concern?
If so, how should I deal with this and design my extension methods as to minimise code changes should this happen?
If the framework is changed so much in the future, there will always be compatibility issues. If a new framework method is added with the same name as your extension method, it is quite likely that they have the same, or at least very similar functionality and a refactoring is due anyways.
I think that the power of the extension methods is too large to ignore just because of this risk.
I'm afraid that the only thing you can do is providing unique enough names to your extension methods so you're 100% sure you will never have a conflict.
Not talking about adding the name of your cat to the method's name, just try to be more creative :)
Use obscure method names that would never be used in the framework.
edit -- perhaps obscure wasn't the most appropriate word, please substitute with meaningful but less common verbage
Attempting to avoid signature conflicts is really the only strategy to avoiding the hassle of code rework (assuming the functionality of the extension method needs to be preserved and not simply converted to the framework's definition of the method).
than just to call the parameter as it is?
If you mean fields, then no. The compiler injects "this" (ldarg.0) whether you use it explicitly (this.foo) or implicitly (foo).
It does, however, take 5 more characters in your source code... so a handful of bytes on your development hard disk. It will make exactly zero difference in the compiled IL or at runtime.
There are two scenarios where use of "this" changes things:
when there is a variable/parameter with the same name (this.foo = foo;)
when resolving extension methods (this.SomeMethod();)
Your question is much too ambiguous to answer definitively but i would still start with a resounding No
then i'd want to know what exactly do you mean with parameter? I would normally interpret it as "argument to a method" but they are not tied to "this" within scope so you probably meant "members" such as fields, properties and/or methods.
If all of my assumptions about how to interpret your question are correct, I stand by my former "No".
But i would like to know where you got that idea from.
I do not know, if it uses more memory, but I don't think so, its only a clear reference, something that would be done under the hood as well by the compiler.
I guess you mean before the variable name? I do not see why it would use more memory. The CLR must be optimize whatever the syntax is to refer to the variable to a way that it doesn't affect the performance (after verification, it will add the this...). So no it doesn't.