-3

I have a folder named "Features" in the solution. This folder can have for example 500 .cs files with classes i them.

In the below example I manually put 2 of those 500 classes in a List:
Features.testclass.cs
Features.testclass2.cs

I wonder how it would be possible to programatically collect ALL classes in those 500.cs files in the Features folder and add them to the list like I do below manually as an example?

Notice that I am saving a new instance of each class in the List as I need to call those classes later on

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public interface IFace { String GetValue(); }
        void GetClasses()
        {
            var MyList = new List<IFace>();
            MyList.Add(new Features.testclass());
            MyList.Add(new Features.testclass2());
        }
    }
}
Andreas
  • 1,121
  • 4
  • 17
  • 34
  • I think, you've missing some tags here. Is this VS Extension? – T.S. Mar 27 '20 at 19:00
  • All of them are in one namespace? – AmirNorouzpour Mar 27 '20 at 19:00
  • I am not sure if I have missed anything? It is Visual Studio Professional 2017 – Andreas Mar 27 '20 at 19:01
  • `void GetClasses` is in namespace `WindowsFormsApp1` and `Features.testclass` is in namespace: `WindowsFormsApp1.Features` – Andreas Mar 27 '20 at 19:02
  • 1
    If your question is how to add files to list, it is simple - `Directory.GetFiles("path", "*.cs").ToList()` – T.S. Mar 27 '20 at 19:05
  • T.S but that will only store strings. That is not what I do in my example :) I store a new instance of a class in the example. – Andreas Mar 27 '20 at 19:06
  • Ok then. What do you need? You need to update your question so that everyone understands what you are looking for and what is not working for you. We don't have to spend time guessing. If you want content of file, get file name first as I said, then `File.ReadAllText`. I am not sure what this question is about? – T.S. Mar 27 '20 at 19:08
  • I think my code shows what I try to do. I will try to update the question also. I have a folder that is called "Features" in the solution. In that folder I have 500 classes files (.cs files). 2 of the is called `testclass.cs` and `testclass2.cs`. I add a `new` instance of those files to a list. Instead of manually adding 500 .cs files like this. How can we iterate all those classes in the `Features` folder and add a `new` instance like I do in my example? – Andreas Mar 27 '20 at 19:11
  • 1
    Are you asking about **files** or are you asking about **classes**? – Tom W Mar 27 '20 at 19:14
  • Tom, I am asking about the .cs files themselves. Please check my original post again. I have updated the question. It tells very clearly now what I am trying to do. – Andreas Mar 27 '20 at 19:15
  • 1
    @Andreas C# is not Java. There's not a 1-to-1 relationship between type definitions and raw source files. – Mathias R. Jessen Mar 27 '20 at 19:17
  • @Mathias, I am not sure exactly what you ment. In my case each .cs file will return a string which works with the code I have. The only problem is if it is possible to collect all 500 files programatically. I beleive it must be possible somehow? – Andreas Mar 27 '20 at 19:20
  • 3
    If you have all classes in `WindowsFormsApp1.Features` namespace, you can list the types and create them with `Activator.CreateInstance` – Sohaib Jundi Mar 27 '20 at 19:23
  • Sohaib, that sounds very interesting. I tried this `MyList.Add((IFace)Activator.CreateInstance("Features", "testclass"))` but I get the error: `System.IO.FileNotFoundException: 'Could not load file or assembly 'Features' or one of its dependencies. The system cannot find the file specified.` "Features" is a folder in the solution to mention there. – Andreas Mar 27 '20 at 19:29
  • 2
    Check here for how to get classes inside a namespace: https://stackoverflow.com/questions/949246/how-can-i-get-all-classes-within-a-namespace. Once you acquires the types, call `Activator.CreateInstance` on them – Sohaib Jundi Mar 27 '20 at 19:34
  • Sohaib, you are a life-saver. Thank you! Now it works. I posted an answer below also. – Andreas Mar 27 '20 at 19:44
  • 1
    @Andreas you keep saying "files" but your posted answer doesn't touch files at all. – Tom W Mar 27 '20 at 19:48
  • Oh perheps it doesn't. Am I collecting ALL functions in all .cs files in the Folder `Features` perheps. However it seems to work for the case I have. In each .cs file I have this code: `public string GetValue() { return "Fred"; }` and I can retreive the `GetValue()` from each `MyList` index below. – Andreas Mar 27 '20 at 19:50
  • After reading these comments I even more convinced that your question is from the beginning wasn't clear at all. If you are working on runtime classes than it bears no relation to any files. And you've been repeating word "files" a lot. You need to pick... classes OR files – T.S. Mar 27 '20 at 19:57
  • Yes you might be right. I only used one class in each .cs file so perheps it was confusing. It is actually classes as you mention. It was just that I thought about collecting all .cs files but what I really does as I understand now is collecting all classes that exists in all .cs files in the `Features` folder. – Andreas Mar 27 '20 at 20:00
  • Amigo... once application is running, there are no files. This is your opportunity to fix the question. If you need to dynamically instantiate certain classes, best way is to mark them with some interface - `IFace` is great. It can be any interface, even one without any API. And then go to assembly, get types, filter the ones that derive from that interface and instantiate all of them. Should be few lines of code. Info is avail all over the place how to do it. – T.S. Mar 27 '20 at 20:07

1 Answers1

-1

This is a solution:

public interface IFace { String GetValue(); }
void GetClasses()
{
    System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly();

    var MyList = new List<IFace>();
    String nameSpace = "WindowsFormsApp1.Features";
    List<String> namespacelist = new List<String>();
    foreach (Type type in asm.GetTypes())
    {
        if (type.Namespace == nameSpace) //"WindowsFormsApp1.Features"
        {
            MyList.Add((IFace)Activator.CreateInstance(type));
        }
    }
}
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
Andreas
  • 1,121
  • 4
  • 17
  • 34
  • 1
    This does not answer the question at all... There is a very good chance that you did not ask what you wanted - so it worth to go back to the question and edit it to match the answer. This answer shows how to load *compiled assembly* and instantiate classes while question asks about *source code* of the classes. – Alexei Levenkov Mar 27 '20 at 19:58
  • Alexei, I changed `files` to `classes` in my first post. I beleive this was the only difference. – Andreas Mar 27 '20 at 20:05
  • @Andreas. No, it still says "How to programatically collect all .cs files in a folder" – T.S. Mar 27 '20 at 20:08
  • I forgot the subject. Now I changed that too. Thank you! – Andreas Mar 27 '20 at 20:10