check if class from assembly contans all methods as in interface - c#

I have custom assembly that is loaded on runtime.
at this point i have code that loads dll and can create new instance of object andexecute method.
How can i verify that the class implements all functions i have defined in interface.
(i am trying to create plug in system with different action that can be switched on runtime, to provide different behaviour).
where my code would be like this is main program:
public Interface IArticleManager{
void SetMenuId(int MenuId);
void SetMenu(string name);
void SetContent(string content);
bool Save();
}
my class libraries (disconnected you can see it from solution)
public class XmlArticle{
public void SetMenuId(int MenuId){
//some implementation
}
public void SetMenu(string name){
//some implementation
}
public void SetContent(string content){
//some implementation
}
public bool Save(){
}
}
public class SqlArticle{
public void SetMenuId(int MenuId){
//some implementation
}
public void SetMenu(string name){
//some implementation
}
public void SetContent(string content){
//some implementation
}
public bool Save(){
}
}

Basically, to rephrase, you want to check if a class defines an interface's contract even if it doesn't explicitly implement that interface?
This is extremely non-trivial and a very, very bad idea. Instead, I would strongly recommend you refactor your plugin interface into a contract assembly, and reference the assembly from both your plugins and main application. Then, your plugins can actually implement the contract and you get compiler protection from messing up the implementation.
If you insist on going down this route, however:
var interfaceType = typeof(IArticleManager);
var targetType = typeof(SqlArticle);
foreach(var member in interfaceType.GetMembers())
{
var targetMember = targetType.GetMember(member.Name);
// compare the arguments, generic constraints, etc here
}
I'll leave it to you to do the comparison, because its quite honestly a substantial amount of coding. You need to check if the member is a property, event, or method, generic or nongeneric, etc.

It seems like what you need to do is move the interface into a separate assembly, which only contains interfaces which is accessible to both the 'main program' and the dynamically loaded DLLs.
So, in order to create a dynamically loaded DLL and expect it to work within your infrastructure, the author will first need to reference the interface assembly and then implement the provided interface.

Checking that a class implements all methods in an interface is of no use unless it actually implements the interface itself - the fact that it has the same method names ends up being just coincidence.
To check that an object instance implements an interface you:
if (obj is IArticleManager)
which would return true.
However if you then want to actually use the interface's methods its better (less casting):
IArticleManager manager = obj as IArticleManager;
if (manager != null)
{ do stuff }

And what is the purpose of IArticleManager when you can not use it anywhere?
That aside, if we accept that you want to make a very loose plugin system, you could mandate that every plugin assembly has exactly one public class and then instantiate that class via reflection, and call out it's methods via reflection while passing appropriate arguments.
As with every plugin or other external code you should validate the output and protect your app from errors (i.e. catch and log the plugin exceptions). This would also handle non valid plugins (ones that don't have the required signature)

Related

Forcing method implementation without interfaces or abstract classes in c#

I'm creating a modular type system were one application(host) loads other modules in to a common UI interface, I have also created an API for this and is available for other users to use.
The API in some instances uses interfaces and abstract classes to force the client using the API to implement the specific methods.
I cannot use interfaces for everything as there are some things were I require putting in my own body so the end user does not need to implement all the unnecessary events and methods himself. EG: So I handle the size changing events myself then pass him the size to a function he implements from called SizeChanged were he can handle his program from the size change.
Abstract classes are what I really want to use but I cannot because the controls the user has may need the x:Name specified in XAML and will recieve the error:
The type ... cannot have a Name attribute. Values types and types without a default constructor can be used as items within ResourceDictionary.
The error occurs because an instance of it needs to be created:
Inherited Window can not have a name?
The only solution available to me that I know of is to use a regular class with virtual methods that can be overridden and that does work fine but it does not force the user to implement my methods that are required.
Is there anything I can do cleanly such as any public implementable or something?
This is the structure:
API:
IContext -> ContextControl -> (Abstract methods)
Module DLL
ContextControl(API) -> AppContextControl(Override methods)
Host Application pull's AppContextControl
I know I can tell the module dev to implement an interface as well as this ContextControl that constrains them to implement the interfaces but it would be much more professional for the compiler to tell them.
In the dev module if I instead of inheriting from ContextControl I implement IContext then I lose all the default bodys and the module dev gotta implement a lot lot more.
Cheers.
The two ways you've described - interfaces and abstract classes - are (as I'm sure you know) the recommended ways to do what you're describing, at least, if you want to enforce the implementation at compile-time.
The only other way I'm aware of is to provide a default implementation that throws a NotImplementedException(). That'll give you a run-time error, but nothing at compile-time, unfortunately.
This may or may not be applicable in your specific situation, but another possible way to get around your limitation is to use a Strategy pattern.
Instead of having the user override members, have them pass in parameters containing the functionality to the constructor. This could either be as delegates or as specific classes you create for the purpose.
Can't you use a combination of inheritance and interfaces? In other words, create virtual methods for the methods that can be overridden and use interfaces to implement methods that must be overridden?
I recently have a similar problem (dnt know it will help in your case). where i have to generate errors at compile time instead of Runtime, with generic functionality. the approach i used was combination of Generics and Interfaces. Examples are...
1) Enum Ex:(C# String enums)
Problem was to set things so that i dnt have to implement every code throughout the project and force Constructor.
public abstract class EnumEx<T> where T : EnumEx<T>
{
private readonly string _displayValue;
private readonly string _value;
protected static ReadOnlyCollection<T> EnumExs;
protected EnumEx(string displayValue, string value)
{
_displayValue = displayValue;
_value = value;
}
public string DisplayValue
{
get { return _displayValue; }
}
public static T FromString(string option)
{
foreach (var enumEx in EnumExs.Where(enumEx => enumEx._value == option))
{
return enumEx;
}
Debug.WriteLine(string.Format("Exception in EnumEX FromString({0})", option));
return null;
}
public override string ToString()
{
return _value ?? string.Empty;
}
}
2) Deep Copy(Generic method to create deep copy of all elements in a collection) + Editable Implementation IEditableObject over custom List
public abstract class CloneAbleBase<T> : ObservableObjectEx, ICloneable, IEditableObject
where T : DataBase<T>, new()
{
protected T CurrentData = new T();
private T _backupData;
private bool _isInEditMode;
public object Clone()
{
var dataObject = (CloneAbleBase<T>) MemberwiseClone();
dataObject.CurrentData = CurrentData.Copy();
return dataObject;
}
public void BeginEdit()
{
if (_isInEditMode) return;
_backupData = CurrentData.Copy();
_isInEditMode = true;
}
public void EndEdit()
{
if (!_isInEditMode) return;
_backupData = default(T);
_isInEditMode = false;
RaisePropertyChanged(string.Empty);
}
public void CancelEdit()
{
if (!_isInEditMode) return;
CurrentData = _backupData;
RaisePropertyChanged(string.Empty);
}
}
In similar way you can create base class for your Window or any control, where you need functionality some sort of generic functionality..
An alternative i can see in your very specific situation is to use interfaces (which, as you said, won't let you inject your own code) and then inherit from the actual type the end user provides and passed in as an interface and inject your own code there at runtime
For example you load all classes implementing IMyPlugin defined as such
public interface IMyPlugin{
void MyEndUserMethod();
void YourMethod();
}
User implements a class that inherits from it
public class UserClass:IMyPlugin{
....
}
You want to force your own code instead of YourMethod, then generate a class at runtime that inherits from UserClass and in YourMethod create your own code and call (or not, depending on your need) base on it. Call base on all other method where the user is to provide the implementation.
This is a bit more work for you but it hides all the uglyness from the end user, simply forcing him to implement the interface. For less uglyness make that interface into 2 interface
public interface IPlugin : IUserPlugin,ICreatorPlugin
And be clear to your users that while the classes must implement IPlugin anything from ICreatorPlugin can be left empty.
An even better solution would be to only expose IUserPlugin and do even more work on your side (your runtime class inherits from the user class AND ICreatorPlugin, and then use duck typing to make it into IPlugin).

Is using var + basic dependency factory more loosely coupled than C# interfaces?

This is a general design question. We often use interfaces to decouple components, write to an interface not an implementation etc. Sometimes interfaces are used w/ a basic injection technique, such as,
interface IMyInterface
{
void DoSomething();
}
static class IMyInterfaceFactory
{
public static IMyInterface GetInstance()
{
return new MyInterfaceInstance();
}
}
class IMyInterfaceConsumer
{
IMyInterface mInterface;
public IMyInterfaceConsumer()
{
this.mInterface = IMyInterfaceFactory.GetInstance();
}
public void UseTheInterface()
{
this.mInterface.DoSomething();
}
}
My question is about using the var keyword instead. Not even using a true C# interface, but still creating an 'interface', in the design sense,
static class IMyInterfaceFactory
{
// of course, this doesnt need to be a single instance
static MyInterfaceInstance mSingleInstance;
// no longer programming to the interface, just returning the instance
public static MyInterfaceInstance GetInstance()
{
// null coalesce
return mSingleInstance ?? (mSingleInstance = new MyInterfaceInstance());
}
}
class IMyInterfaceConsumer
{
public void UseTheInterface()
{
// shorthand way, could also omit var, too
var myInterface = IMyInterfaceFactory.GetInstance();
myInterface.DoSomething();
}
}
This way I still only need to change the factory once, and as long as whatever instance it returns supports the methods that need to be consumed, it will work. The advantage however is that the producing and consuming objects dont need to even know about any explicit interface, none exists. It could also cleanly support an interface with more than just a couple methods (prevent bloated interface declarations).
One obvious downside is that everytime you want to consume a method from the 'interface', the factory will potentially have to re-instantiate the class, unless there is a single instance cached (as above) or some memoization technique used.
Pros/cons of this approach? Is this a common practice?
There is nothing dynamic or loose about the var keyword. It triggers static type inference at compile time.
Your second piece of code behaves identically to
public void UseTheInterface()
{
// shorthand way, could also omit var, too
MyInterfaceInstance myInterface = IMyInterfaceFactory.GetInstance();
myInterface.DoSomething();
}
The factory function is still strongly typed. In fact, by removing the interface, you've made consumer code much more tightly coupled.
Var keyword is still technically strongly typed, so your code does know what class/interface it is. If you planned on dumping it into an object then we are saying that the rest of your code has no clue what is coming out of that factory. I wouldn't suggest that though since that causes you to cast that object to utilize anything in it.
I'm not sure where you are trying to go with the "prevent bloated interface declarations" but you could do polymorphism through extending a base class or an abstract class as well. That would make it so any code that is common between the child classes could be left alone and any specific code (methods or properties) for each child class could be overridden.
If you are looking to change out the interface all together you will need to implement an interface in the interface, see this post. So you will basically have interface A only have the method DoStuff() and other interfaces that inherit from this interface could be used polymorphically like you are describing.
interface A
{
DoStuff();
}
interface B : A
{
DoSomethingElse();
}
class C : B
{
DoStuff(){}
DoSomethingElse(){}
}
By the way, your "single instance cached" code above is close to something called a singleton pattern.

Porting code from Reflection to using an Interface, some API's not implemented

I have some old C# plugin code that was implemented strictly with Reflection. In fixing some C# 2.0 -> 4.0 compatibility issues ("Load from Remote Source") I've decided to get rid of the old reflection code and replace it with an interface. The interface is needed because the Plugins now need to be loaded into their own AppDomain and then marshalled across.
I can go through the source for hundreds of plugins and simply make them all implement the new IPlugin interface with a simple search-and-replace. This works nicely except in one crucial place. And I'm looking for an easy out.
The method RunPlugin() can be implemented in one of two ways, but never both: Either with an argument or without. If I include this in the interface, I'd have to implement both in each of the plugins. The caller calls the one or no argument method based on which one is implemented. The calling assembly figures this out now by reflection.
To avoid that I can create a wrapper class for the plugins, that wrapper implements the interface, but then I'd have to heavily edit each of the plugins to include an override for each of the API's many methods.
Some sample code (this doesn't necessarily work! It's all in transition right now!):
The interface (sample):
// In IPlugin.cs / IPlugin.dll
namespace Plugin
{
public interface IPlugin
{
// Many, many happy API things like this...
void SetupOptions(Hashtable options);
// (examples elided)
// And then these two... either one or the other
// is implemented, but not both.
XmlDocument RunPlugin(Updater u);
XmlDocument RunPlugin();
}
}
The called Assembly... I have lots of these. I can add the ": IPlugin" fairly easily. This won't compile, obviously, because it doesn't implement the one-argument RunPlugin().
namespace Plugin
{
public class FileMaintenance : IPlugin
{
public void SetupOptions(Hashtable options)
{ // Code elided
}
public XmlDocument RunPlugin()
{ // Code elided
}
}
}
And finally, the calling code. This is actually how it used to look, back in the reflection code:
public XmlDocument RunPlugin(PluginRunner.Updater u)
{
Type [] paramTypes = new Type [0];
MethodInfo runInfo = repType.GetMethod("RunPlugin", paramTypes);
if (runInfo == null)
{
paramTypes = new Type [1];
paramTypes[0] = u.GetType();
runInfo = repType.GetMethod("RunPlugin", paramTypes);
if (runInfo == null)
throw new Exception;
}
Object[] parameters;
if ( paramTypes.Length == 0)
parameters = new Object[0];
else
{
parameters = new Object[1];
parameters[0] = u;
}
Object returnVal;
try
{
returnVal = runInfo.Invoke(repObj,parameters);
}
catch (Exception e)
{
}
// Rest of code omitted
}
Remember: I'm looking for a nice balance between the right way to fix this old code, and doing the minimal amount of editing code by hand.
I would advocate creating two additional interfaces:
public interface IRunnablePlugin : IPlugin
{
XmlDocument RunPlugin();
}
public interface IParamRunnablePlugin : IPlugin
{
XmlDocument RunPlugin(object parameter);
}
Then have all of your plugins implement one or the other. The only time you'll have to make a distinction is when actualling calling RunPlugin. All other times you can refer to it as a simple IPlugin.
For example, to perform the call, you'd do something like this:
IPlugin plugin = ...;
IRunnablePlugin runnable = plugin as IRunnablePlugin;
IRunnableParamPlugin param = plugin as IRunnableParamPlugin;
XmlDocument output;
if(param != null)
{
output = param.RunPlugin(parameter);
}
else if(runnable != null)
{
output = runnable.RunPlugin();
}
else
{
throw new InvalidOperationException();
}
Note that there is technically no limitation that permits the developer to implement only one of the versions, but that should hopefully not be an issue. In this code, you're checking for the presence of the parameterized version first, then the parameterless version, then throwing an exception if neither is found.
Unfortunately having one or the other RunPlugin methods was the Achilles heal that got added to this design from the getgo. That was a precarious design decision, it's going to be hard to deal with it.
One possibility is to add both overloads to IPlugin, and let plugins indicate the one they didn't implement by throwing NotImplementedException. That probably doesn't buy you much, it might not buy you anything.
Another possibility is two interfaces, IPlugin and IPluginWithArgs, and detect which interface a given plugin is implementing and go from there. Also ugly.
Another possibility is an extension method public static void RunPlugin(this IPlugin plugin) that basically hides and tidies up the reflection you've already got going. I don't think this buys you anything either.
You could have one base interface like so:
public interface IPlugin {
// Many, many happy API things like this...
void SetupOptions(Hashtable options);
// (examples elided)
XmlDocument RunPlugin();
}
//
// And another interface extending the IPlugin that defines the update version
//
public interface IUpdaterPlugin : IPlugin {
XmlDocument RunPlugin(Updater u);
}
To run the appropriate plugin...
if( plugin is IUpdaterPlugin)
plugin.RunPlugin(updater);
else if(plugin is IPlugin)
plugin.RunPlugin();
So, you say...
To avoid that I can create a wrapper class for the plugins, that wrapper
implements the interface, but then I'd have to heavily edit each of the
plugins to include an override for each of the API's many methods.
I'm not quite sure I understand the problem with the wrapper class, but we might be thinking about different things.
The wrapper class I'm thinking about would take the interface with zero parameters and make it look like the interface with one parameter. That parameter would simply be ignored when "RunPlugin" was called.
This would remove any branching on types for your interfaces and you'd only have to create this one class - it could wrap any instance of the no-parameter interface. So there shouldn't be any special code needed for each plugin. Just create the wrapper when you create the instance of the plugin.
(By the way, this is the Adapter pattern.)

C#: Optional method

I have an object that implements an interface. I want to call on the object's method if it is implemented. What's the best way in doing this?
Update
A few of you mentioned that my question was vague. Sorry about that. When i said "if it is implemented" i meant "if it is callable". Thanks for your answers and effort guys (or girls!). I'm amazed how much developer support there is on this website.
If this really the way you need it to work, an interface is the wrong choice. Instead, you could have an abstract class from which your class derives with a virtual method. Virtual allows it to be overridden, but does not require it. Since a virtual method has an implementation, it cannot be part of an interface.
Not quite sure what you mean by "if it is implemented." If the method is in the interface and your object implements the interface it must implement the method.
If you want to test if an object implements the interface so you can call the method, you can do it like so:
interface IFoo { void Bar(); }
object o = GetObjectThatMayImplementIFoo();
IFoo foo = o as IFoo;
if (foo != null) {
foo.Bar();
}
I think that's what you were asking?
Create two interfaces, and inherit both interfaces where all methods are required. Inherit only one of the interfaces where the optional methods aren't required.
You can also create a base interface, from which all your interface will inherit, for OOP uses.
I think what you're really looking for is a partial method. These are new in .NET 3.5. You simply declare the method as "partial":
partial void OnLoaded();
The method can be called normally:
OnLoaded();
The neat thing is that if the method is not implemented anywhere, the compiler is smart enough not to generate the call.
This was implemented primarily for LINQ to SQL and for Entity Framework; this allows generated code (using partial classes) to define and call methods without knowing whether they are implemented.
Mixing partial methods with interfaces would be interesting (I haven't tried it), but my first try would be declaring a partial method in the interface.
Shouldn't the object's class implement every method of the interface?
If the object's class inherits from an abstract class, it is possible that it might not override("implement") some methods. Perhaps you are mixing the two up in your mind.
As with the other answers, I'm not sure what you mean. The closest that a class implementing an interface can get to not implementing one of the interface methods is throwing a NotImplementedException. The way to handle this is to specifically catch that exception when calling the method. However, the whole point of an interface is to define a contract between classes, so maybe some clarification would help.
My first response is don't do this. It creates conditional logic around the possibility of a method being there, it goes against the statically typeness of C# and breaks a couple of the SOLID principles. My experience tells me this is the wrong path to walk down.
With that said it can be done via Reflection or using the 'is/as' solution wojo demonstrates.
This type of behavior might be better implemented in a dynamic language. It sounds similar to Duck typing. I'm not a dynamic language guy, but if you have unit tests, it may be alright.
You cannot really know if the method is actually implemented (or if the class just has a "dummy" implementation). Therefore, you may use a pattern such as one of the following to find out if a specific method is supported:
-> Have multiple interfaces and see if the class actually implements it; this is probably the cleanest way to deal with it, but it may leave you with a large number of different interfaces, which may not be desirable:
IIntfA = inst as IIntfA;
if (inst != null) {
// inst seems to be implemented
}
-> Use methods in the TryXxx style, which return true if they were successfull (like TryParse() etc.).
-> Use NotImplementedException - but note that catching those is very expensive and should only be used for calls which are performed rarely, or where a missing implementation is not expected. The Stream class works like this, for instance if it cannot be written to (but additionally there is a property telling what the class supports, e.g. IsWritable in the Stream class).
Hey guys, don't forget the "is" keyword :P
You can check if an object implements an interface like this too:
if (inst is IInterface)
{
// you can safely cast it
}
I prefer it that way but of course you could also use the "as" keyword
IInterface a = inst as IInterface;
if (a != null)
{
// use a, already casted
}
Depending on how you're referencing an object, certain members will be visible. An interface might be implicitly defined or explicitly defined, or might be implemented by a derived class and you're using a base class reference. In other words, it's not always immediately evident all the available members on an object.
So if you want to test for implementation of a certain interface (ISomething) by your object (yourObj), one choice is testing the data type, using reflection. Based on the result of this test, you can explicitly cast an implementing object into the interface Type and use its members...
if (yourObj is ISomething)
((ISomething)yourObj).DoSomething();
This is the same thing done another way (more "wordy" using method calls):
if (typeof(ISomething).IsAssignableFrom(yourObj.GetType()))
((ISomething)yourObj).DoSomething();
This sample assumes the ISomething interface is defined as:
public interface ISomething {
void DoSomething();
// other members ...
}
In summary, this code says: if the interface ISomething Is-Assignable-From your object of choice, then your object implements that interface and therefore has those public members.
I don't know if you might be looking for something like this. This uses an attribute that you can flag a method with whether or not it is implemented. Next I added an extension method to the interface to allow for checking if ithe method is implemented. Finally, the code will allow you to ask an object if the method is implemented. I don't like this but it might be what you are looking for.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace ConsoleApplication1
{
public static class Program
{
static void Main(string[] args)
{
EmployeeA empA = new EmployeeA();
if (empA.IsImplemented("TestMethod"))
empA.TestMethod();
EmployeeB empB = new EmployeeB();
if (empB.IsImplemented("TestMethod"))
empB.TestMethod();
Console.ReadLine();
}
public static bool IsImplemented(this IEmp emp, string methodName)
{
ImplementedAttribute impAtt;
MethodInfo info = emp.GetType().GetMethod(methodName);
impAtt = Attribute.GetCustomAttribute(info, typeof(ImplementedAttribute), false)
as ImplementedAttribute;
return (impAtt == null) ? true : impAtt.Implemented;
}
}
public class EmployeeA : IEmp
{
#region IEmp Members
[Implemented(false)]
public void TestMethod()
{
Console.WriteLine("Inside of EmployeeA");
}
#endregion
}
public class EmployeeB : IEmp
{
#region IEmp Members
[Implemented(true)]
public void TestMethod()
{
Console.WriteLine("Inside of EmployeeB");
}
#endregion
}
public class ImplementedAttribute : Attribute
{
public bool Implemented { get; set; }
public ImplementedAttribute():this(true)
{
}
public ImplementedAttribute(bool implemented)
{
Implemented = implemented;
}
}
public interface IEmp
{
void TestMethod();
}
}
EDIT: After original author reworded question, you definitely just want to implement the interface guranteeing the method does exist. I will leave above code for curiosity sake.

How can you require a constructor with no parameters for types implementing an interface?

Is there a way?
I need all types that implement a specific interface to have a parameterless constructor, can it be done?
I am developing the base code for other developers in my company to use in a specific project.
There's a proccess which will create instances of types (in different threads) that perform certain tasks, and I need those types to follow a specific contract (ergo, the interface).
The interface will be internal to the assembly
If you have a suggestion for this scenario without interfaces, I'll gladly take it into consideration...
Not to be too blunt, but you've misunderstood the purpose of interfaces.
An interface means that several people can implement it in their own classes, and then pass instances of those classes to other classes to be used. Creation creates an unnecessary strong coupling.
It sounds like you really need some kind of registration system, either to have people register instances of usable classes that implement the interface, or of factories that can create said items upon request.
You can use type parameter constraint
interface ITest<T> where T: new()
{
//...
}
class Test: ITest<Test>
{
//...
}
Juan Manuel said:
that's one of the reasons I don't understand why it cannot be a part of the contract in the interface
It's an indirect mechanism. The generic allows you to "cheat" and send type information along with the interface. The critical thing to remember here is that the constraint isn't on the interface that you are working with directly. It's not a constraint on the interface itself, but on some other type that will "ride along" on the interface. This is the best explanation I can offer, I'm afraid.
By way of illustration of this fact, I'll point out a hole that I have noticed in aku's code. It's possible to write a class that would compile fine but fail at runtime when you try to instantiate it:
public class Something : ITest<String>
{
private Something() { }
}
Something derives from ITest<T>, but implements no parameterless constructor. It will compile fine, because String does implement a parameterless constructor. Again, the constraint is on T, and therefore String, rather than ITest or Something. Since the constraint on T is satisfied, this will compile. But it will fail at runtime.
To prevent some instances of this problem, you need to add another constraint to T, as below:
public interface ITest<T>
where T : ITest<T>, new()
{
}
Note the new constraint: T : ITest<T>. This constraint specifies that what you pass into the argument parameter of ITest<T> must also derive from ITest<T>.
Even so this will not prevent all cases of the hole. The code below will compile fine, because A has a parameterless constructor. But since B's parameterless constructor is private, instantiating B with your process will fail at runtime.
public class A : ITest<A>
{
}
public class B : ITest<A>
{
private B() { }
}
Juan,
Unfortunately there is no way to get around this in a strongly typed language. You won't be able to ensure at compile time that the classes will be able to be instantiated by your Activator-based code.
(ed: removed an erroneous alternative solution)
The reason is that, unfortunately, it's not possible to use interfaces, abstract classes, or virtual methods in combination with either constructors or static methods. The short reason is that the former contain no explicit type information, and the latter require explicit type information.
Constructors and static methods must have explicit (right there in the code) type information available at the time of the call. This is required because there is no instance of the class involved which can be queried by the runtime to obtain the underlying type, which the runtime needs to determine which actual concrete method to call.
The entire point of an interface, abstract class, or virtual method is to be able to make a function call without explicit type information, and this is enabled by the fact that there is an instance being referenced, which has "hidden" type information not directly available to the calling code. So these two mechanisms are quite simply mutually exclusive. They can't be used together because when you mix them, you end up with no concrete type information at all anywhere, which means the runtime has no idea where to find the function you're asking it to call.
So you need a thing that can create instances of an unknown type that implements an interface. You've got basically three options: a factory object, a Type object, or a delegate. Here's the givens:
public interface IInterface
{
void DoSomething();
}
public class Foo : IInterface
{
public void DoSomething() { /* whatever */ }
}
Using Type is pretty ugly, but makes sense in some scenarios:
public IInterface CreateUsingType(Type thingThatCreates)
{
ConstructorInfo constructor = thingThatCreates.GetConstructor(Type.EmptyTypes);
return (IInterface)constructor.Invoke(new object[0]);
}
public void Test()
{
IInterface thing = CreateUsingType(typeof(Foo));
}
The biggest problem with it, is that at compile time, you have no guarantee that Foo actually has a default constructor. Also, reflection is a bit slow if this happens to be performance critical code.
The most common solution is to use a factory:
public interface IFactory
{
IInterface Create();
}
public class Factory<T> where T : IInterface, new()
{
public IInterface Create() { return new T(); }
}
public IInterface CreateUsingFactory(IFactory factory)
{
return factory.Create();
}
public void Test()
{
IInterface thing = CreateUsingFactory(new Factory<Foo>());
}
In the above, IFactory is what really matters. Factory is just a convenience class for classes that do provide a default constructor. This is the simplest and often best solution.
The third currently-uncommon-but-likely-to-become-more-common solution is using a delegate:
public IInterface CreateUsingDelegate(Func<IInterface> createCallback)
{
return createCallback();
}
public void Test()
{
IInterface thing = CreateUsingDelegate(() => new Foo());
}
The advantage here is that the code is short and simple, can work with any method of construction, and (with closures) lets you easily pass along additional data needed to construct the objects.
Call a RegisterType method with the type, and constrain it using generics. Then, instead of walking assemblies to find ITest implementors, just store them and create from there.
void RegisterType<T>() where T:ITest, new() {
}
I don't think so.
You also can't use an abstract class for this.
I would like to remind everyone that:
Writing attributes in .NET is easy
Writing static analysis tools in .NET that ensure conformance with company standards is easy
Writing a tool to grab all concrete classes that implement a certain interface/have an attribute and verifying that it has a parameterless constructor takes about 5 mins of coding effort. You add it to your post-build step and now you have a framework for whatever other static analyses you need to perform.
The language, the compiler, the IDE, your brain - they're all tools. Use them!
No you can't do that. Maybe for your situation a factory interface would be helpful? Something like:
interface FooFactory {
Foo createInstance();
}
For every implementation of Foo you create an instance of FooFactory that knows how to create it.
You do not need a parameterless constructor for the Activator to instantiate your class. You can have a parameterized constructor and pass all the parameters from the Activator. Check out MSDN on this.

Categories

Resources