I hope I understand you correctly.
The class that you create in the type project consists of several objects that have different types of behavior, but the same data elements, and you would like to be able to easily use them in your projects without the hassle of explicitly listing these objects.
I would create some basic interface that implements all my objects in the Types project. Then I used the Factory class, which would use reflection to collect all objects that implement the specified interface.
public interface iFoo { string FoundItem { get; set; } string Expression { get; } string Value { get; set; } void sharedFunctionName(); } public static class FooFactory { public static List<iFoo> GetTypeList() { List<iFoo> types = new List<iFoo>(); types.AddRange(from assembly in AppDomain.CurrentDomain.GetAssemblies() from t in assembly.GetTypes() where t.IsClass && t.GetInterfaces().Contains(typeof(iFoo)) select Activator.CreateInstance(t) as iFoo); return types; } }
Then your Reader will receive all the necessary information for the supported types, if you do not have to manually quote it.
Since I assume that the type of the value will be different at some point, you can use the general interface as follows:
public interface iFoo { string FoundItem { get; set; } string Expression { get; } void sharedFunctionName(); } public interface iFoo<T> : iFoo { T Value { get; set; } } public static class FooFactory { public static List<iFoo> GetTypeList() { List<iFoo> types = new List<iFoo>(); types.AddRange(from assembly in AppDomain.CurrentDomain.GetAssemblies() from t in assembly.GetTypes() where t.IsClass && t.GetInterfaces().Contains(typeof(iFoo)) select Activator.CreateInstance(t) as iFoo); return types; } } public class FooBar : iFoo<int> { }
In this example, the basic iFoo interface is supported to facilitate the discovery process. Using a universal interface would keep the type code safe (as opposed to using the type type value), but you will have to add some logic when restoring your objects in order to be able to properly access your value.
In addition, if you ever need to create functions that require sharing within all of your objects, you can add extension methods in the Factory and VoilΓ class.
EDIT:
Based on new information:
Your types correspond to the type of data that you find in the file based on some regular expression. There may be another type of conversion based on user choice and type.
We know that the user will need to select a mode from the list, and this will affect the conversion applied to types.
So here is what I will do: I would move the conversion logic directly to the Type class, the polymofit will take care of which conversion will be called.
I would put RegularExpression to define the type in the type itself, this will allow you to use reflection and discussion of the Factory class more efficiently.
Thus, everything is standard. Your reader knows about any new type that you create in the type project without manual intervention, and once the correct conversion is found, you can apply, and the source string is always available.
public enum UserMode {Mode1, Mode2}; public interface iType { string Expression {get;} string OriginalString {get; set;} string Transform(UserMode Mode); iType getNewInstance(string OriginalString); } public class Type1 : iType { public string Expression {get { return "RegularExpression"; }} public string OriginalString {get; set;}
Now, all you will need to do is if the matching expression from iTypes is listed. When you play a match, follow these steps:
var TransformationReady = from t in TypeFactory.GetTypeList() where Regex.IsMatch(YourFileLine, t.Expression) select t.getNewInstance(Regex.Match(YourFileLine, t.Expression));