Roslyn - Find reference using fully qualified Name - c#

I have below classes and respective public properties. They are currently called by different projects part of a solution. I have a need that I would like to find the references / callers for Class2 and Class3 properties. I am using SymbolFinder.FindCallersAsync which provides me all the callers who is calling these properties. I get the symbol info which needs to be passed to FindCallersAsync using GetSymbolsWithName. This fetches the callers of Class1 which I don't want to have. Is there a way that we can get symbol based on the actual associated property of a particular class. Also is there a recommendation between using FindReferencesAsync vs FindCallersAsync.
Class1-> LoanId
Class2-> LoanId, InterestRate
Class3->LoanId, NumberofMonths

Related

How to list inheritance in protobuf when child classes are not in same assembly

In our application, we have the model(to be transfered over WCF with protobuf) in different packages, the "common" project is referenced by almost all the childs projects. In the childs projects we find all the classes specifics to some certains business area.
All the DLL are not shipped, depending on what feature the customer baught.
I know that one way of specifying the possibles childs classes is like:
[ProtoContract]
[ProtoInclude(100, typeof(Derived))]
[ProtoInclude(101, typeof(Derive2))]
public class Base {
[ProtoMember(Order=1)]
int Old;
}
But in my case, I cannot reference the projects that contains Derived and Derived2 classes(it would cause a cyclic reference, and even more important, it's weird that the parent has to know all its child).
With the default DataContractSerializer it was possible to specify a way to find which type of class we are using, is there a way to achieve this? Or I just cannot use protobuf with my constraints?
it's weird that the parent has to know all its child.
No, that's actually normal; see also [XmlInclude] and [KnownType], which work the same way
However, to avoid the circular reference issue with typeof, you can use the assembly qualified name as a string. To get the assembly qualified name, look at what typeof(Foo).AssemblyQualifiedName writes, then:
[ProtoInclude(100, "your assembly qualified name here")]
[ProtoInclude(101, "another assembly qualified name here")]
Another option is to configure everytime at runtime with RuntimeTypeModel.Default[typeof(RootType)].AddSubType(...) - but: you still need to be able to configure it reliably with reliable integers.

C# namespaces: how to follow standards without causing annoying conflicts?

I'm working on a C# library (let's just call it "Foo" for the sake of this question). It has some needs very similar to standard .NET needs: for example, it provides some drawing services, and some conversion services.
For the sake of familiarity and users of the library being able to guess what things are called, I'd like to follow the .NET standard, and name these parts of the library Foo.Drawing and Foo.Convert (and so on). But I'm finding that in actual use, this causes pain. People almost always have "using System;" at the top of each file, and when using this library, they want to have "using Foo;" as well. But now they have two Drawing and two Convert modules, and hilarity ensues.
For example, now instead of just using Drawing.Color for a parameter or variable type, you have to explicitly spell out System.Drawing.Color, or the compiler complains that Foo.Drawing doesn't have a Color type. Similarly, you want to use a standard Convert.ToInt32, you have to say System.Convert.ToInt32, even though you're already using System, because otherwise it finds Foo.Convert and fails to find ToInt32.
I understand why all this is as it is, but I'm still new to the C# community, so I don't know which is the most standard solution:
Leave it this way, and expect users to use fully-qualified names where necessary?
Rename the conflicting modules to something else (maybe Foo.Graphics instead of Foo.Drawing, and Foo.Conversion instead of Foo.Convert)?
Use some prefix on the standard names (Foo.FDrawing and Foo.FConvert)?
Something else?
Any advice from you more experienced C# gurus will be appreciated!
You can use namespace aliasing :
using System;
using FConvert = Foo.Convert;
public class Bar
{
public void Test()
{
var a = Convert.ToInt32("1");
var b = FConvert.ToInt32("1");
}
}
One of the main usage of namespaces is to avoid name clashing.
It means that namespaces allow developers to create types with identical names, as long as the belong to different namespaces.
A library usually have at least a root namespace, and possibly nested namespaces that logically groups the related types.
Name your types as you wish, as long as the names are meaningful and represent what the type really are. A client of your library expects a type named Animal to represent an Animal, not something else. The same applies for naming namespaces.
However, avoid at all cost the names from System, since it will be really annoying for your library clients (as you described) to deal with conflicting names all over the place.
A common way to deal with conflicting namesapces inside a class is to use namespace aliasing:
using FooConvert = Foo.Convert;
using BarConvert = Bar.Convert;

C#.NET: internal class accessible from another class using Type.GetType and Activator.CreateInstance?

I know that access modifier internal declared on a class makes it accessible from inside same assembly.
However, in my case another assembly is able to access internal class in another assembly using Type.GetType and is also able to create its object using Activator.CreateInstance() successfully.
I want to know is it really possible to be able to access an internal class in another assembly using Type.GetType() in another assembly? If not , then am i missing something?
Additional Details :
I am going to specify a link containing class diagram of my Domain Driven Design (Model and Infrascture Layers) which use three assmbelies/projects:
For the sake of ease, i am going to explain bits about above class diagaram:
Most external boundaries/rectangles are for assemblies/projects
namely;
A) sharemanagement.model,
B) sharemanagement,
C) sharemanagement.infrastructure.repositories
such that sharemanagement is like core (or library) which is referenced by sharemanagement.model and sharemanagement.infrastructure.repositories but sharemanagent assembly does not reference any of these two (because sharemanagement is the core/base library/assemblies on which other assemblies depend.
rectangles inside rectangles are sub-directories.
Now, sharemanagement.model requests sharemanagement (using its repositoryFactory) to return an instance of CompanyRepository (defined in Sharemanagement.Infrastructure.Repositories) which sharemanagement obtains using Type.GetType and Activator.CreateInstance()
And, while creating instance of instance of CompanyRepository ( using Activator.CreateInstance() as mentioned above), the base class of CompanyRepository namely "SQLRepositoryBase" (defined in Sharemanagement ) gets an instance of EntityFactory (defined in Sharemanagement.Infrastructure.Repositories) using Type.GetType (from inside buildEntityFactory method of) EntityFactoryBuilder class.
Main point to note is that CompanyFactory is internal class and defined inside assembly "sharemanegement.infrastructure.repositories" whereas EntityFactoryBuilder.buildentityFactory() class is defined in assembly "sharemanagement".
However, in my case another assembly is able to access internal class in another assembly using Type.GetType and is also able to create its object using Activator.CreateInstance() successfully.
Indeed, assuming the code trying to do so has an appropriate trust level. Indeed, fully trusted code can do all kinds of things with reflection, including changing private fields. Code operating in a reduced trust environment can't do these things.
Internal entities might be inaccessible in obfuscated assemblies.

Type.GetType() visibility issue between projects (Visual C#)

I ran into a peculiarish problem. I am working on a dynamic factory project and my intention is to be able to create new objects based on an XML file. My problem is this:
I have a separate project for the base classes for the factory where I have
public abstract class DynamicContentFactory<T, Params> where T: class where Params: DynamicParameters
In this abstract class I have a static method Create as follows
public static T Create(Params data)
Params only includes one string as a default called Type. I want to limit the creation of objects to the same namespace as the base class T, so I do the following:
string namespaceStr = typeof(T).ToString();
namespaceStr = namespaceStr.Substring(0, namespaceStr.LastIndexOf('.') + 1);
Type type = Type.GetType(namespaceStr + data.Type);
In my main project, I have a specific factory class
public class ItemFactory : DynamicContent.DynamicContentFactory<ItemFactory, ItemParameters>
{
}
The problem is that when I call ItemFactory.Create, the Type.GetType returns null. ItemFactory resides in the same namespace as the Items I want it to create, but the base class resides in another. Is there any way around this?
I have tried changing the parameter of Type.GetType() to typeof(T).ToString() in order to test whether it can find it and it did not find it either. I can't create a link from my DynamicContent project to my main project because a link to the other way already exists. I feel it is silly that it cannot even find the type of the class it was initialized in.
So my question is: What would be the best way to go around this? I would prefer maintaining my DynamicContent project in a separate project as a separate library rather than having to include it in my main project. Is there a way to make it find the classes or do I have to create third project for the types I want to initialize with this in order to be able to reference it from both the main project and the DynamicContent project?
BR,
-Sami
Behavior you are observing is expected - Type.GetType
typeName - The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.
Note that your current code works because it falls under "currently executing assembly" portion of the specified behavior where just namespace+name is enough.
You should specify full name of the type when requesting it, but you can check what namespace the type will use.
You can switch to Assembly.GetType instead of Type.GetType and use T's assembly to lookup types you want to create.
Alternative is to scan all loaded assemblies for type you want, but it may be not enough if the type is coming from not-yet-loaded assembly.
Remainder: namespace names in .Net don't mean much - they are convention to make code more readable, but there is no particular link between assembly and namespaces that are implemented in it.

What is Reflection property of a programming language?

Its said that most high-level dynamically types languages are reflexive. Reflection (computer programming) on Wikipedia explains but it doesn't really give a very clear picture of what it means. Can anyone explain it in a simpler way by a relevant example?
To give you a example how to use Reflection in a practical way:
Let's assume you are developing an Application which you'd like to extend using plugins. These plugins are simple Assemblies containing just a class named Person:
namespace MyObjects
{
public class Person
{
public Person() { ... Logic setting pre and postname ... }
private string _prename;
private string _postname;
public string GetName() { ... concat variabes and return ... }
}
}
Well, plugins should extend your application at runtime. That means, that the content and logic should be loaded from another assembly when your application already runs. This means that these resources are not compiled into your Assembly, i.e. MyApplication.exe. Lets assume they are located in a library: MyObjects.Person.dll.
You are now faced with the fact that you'll need to extract this Information and for example access the GetName() function from MyObjects.Person.
// Create an assembly object to load our classes
Assembly testAssembly = Assembly.LoadFile(Application.StartUpPath + #"MyObjects.Person.dll");
Type objType = testAssembly.GetType("MyObjects.Person");
// Create an instace of MyObjects.Person
var instance = Activator.CreateInstance(objType);
// Call the method
string fullname = (string)calcType.InvokeMember("GetName",
BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
null, instance, null);
As you can see, you could use System.Reflection for dynamic load of Resources on Runtime. This might be a help understanding the ways you can use it.
Have a look on this page to see examples how to access assemblys in more detail. It's basically the same content i wrote.
To better understand reflection, think of an interpreter that evaluates a program. The interpreter is a program that evaluates other programs.
The program can (1) inspect and (2) modify its (a) own state/behavior, or the state/behavior of the interperter running it (b).
There are then four combinations. Here is an example of each kind of action:
1a -- Read the list of fields an object has
2a -- Modification of the value of one field based on the name of the field; reflective invocation of methods.
1b -- Inspect the current stack to know what is the current method that is executed
2b -- Modify the stack or how certain operations in the language are executed (e.g. message send).
Type a is called structural reflection. Type b is called behavioral reflection. Reflection of type a is fairly easy to achieve in a language. Reflection of type b is way more complicated, especially 2b--this is an open research topic. What most people understand by reflection is 1a and 2a.
It is important to understand the concept of reification to understand reflection. When a statement in the program that is interpreted is evaluated, the interpreter needs to represent it. The intepreter has probably objects to model field, methods, etc. of the program to be interpreted. After all, the interpreter is a program as well. With reflection, the interpreted program can obtain references to objects in the interpreter that represent its own structure. This is reification. (The next step would be to understand causal connection)
There are various kinds of reflective features and it's sometimes confusing to understand what's reflective or not, and what it means. Thinking in term of program and interpreter. I hope it will help you understand the wikipedia page (which could be improved).
Reflection is the ability to query the metadata the program that you wrote in run-time, For example : What classes are found inside an assembly, What methods, fields and properties those classes contains, and more.
.net contains even 'attributes', those are classes that you can decorate with them classes, methods, fields and more, And all their purpose is to add customized metadata that you can query in run-time.
Many time details depend on metadata only. At the time of validation we don't care about string or int but we care that it should not be null. So, in that case you need a property or attribute to check without caring about specific class. There reflection comes in picture. And same way if you like to generate methods on a fly, (as available in dynamic object of C# 4.0), than also it is possible using reflection. Basically it help to do behavior driven or aspect oriented programming.
Another popular use is Testing framework. They use reflection to find methods to test and run it in proxy environment.
It is the ability of a programming langauge to adapt it's behaviour based upon runtime information.
In the .Net/C# world this is used frequently.
For example when serializing data to xml an attribute can be added to specify the name of the field in the resultant xml.
This is probably a better question for programmers.stackexchange.com.
But it basically just means that you can look at your code from within your code.
Back in my VB6 days there were some UI objects that had a Text property and others that had a Description (or something other than 'Text' anyway, I forget). It was a pain because I couldn't encapsulate code to deal with both kinds of objects the same way. With reflection I would have at least been able to look and see whether an object had a Text or a Description property.
Or sometimes objects might both have a Text property, but they derive from different base classes and don't have any interface applied to them. Again, it's hard to encapsulate code like this in a statically typed language without the help of reflection, but with reflection even a statically typed language can deal with it.

Categories