I understand this is only possible with a workaround. But why?
I want to add plugin support to my app. So I designed an abstract class that all future plugins will need to implement. Every plugin must implement a GetVersion() method like in this example code:
public abstract class Plugin
{
public abstract int GetVersion();
}
public class MyPlugin : Plugin
{
public override int GetVersion()
{
return 1;
}
}
This of course works perfectly as long as I instantiate the plugin before calling the GetVersion() method.
But if I want to get the version number of the plugin before creating an instance of it? To check compatibility for example?
public class Program
{
public Program()
{
if (MyPlugin.GetVersion() > 1)
{
PluginLoader.Load(new MyPlugin());
}
}
}
Although it might not answer directly your question "WHY" I think below solution might be usefull in your scenario:
Use assembly version attribute:
Assembly thisAssem = typeof(MyPlugin).Assembly;
AssemblyName thisAssemName = thisAssem.GetName();
Version ver = thisAssemName.Version;
It never can be done by C# because a static method cannot be implemented in derived classes.
Like the workaround, you can create a static factory to create the instance.
public abstract class Plugin
{
public abstract int GetVersion();
}
public class FactoryPlugin<T> where T : Plugin, new()
{
public static int GetVersion()
{
return new T().GetVersion();
}
}
public class Program
{
public Program()
{
if (FactoryPlugin<MyPlugin>.GetVersion() > 1)
{
}
}
}
Consider using the Factory pattern in a way similar to what a COM class factory does. You create two classes, your useful class, and a class factory class. Your class factory class implements IPluginFactory. You package it with your Plugin. The plugin factory has vary simple methods, but one of them allows your Plugin to be created. It's close to what #ThierryV showed, but without static methods. So the process is:
Use whatever you are planning to use to store and instantiate your plugins, but instead of instantiating a plugin, you instantiate the appropriate Plugin Factory
You can have the Plugin factory do what ever you want -- get detailed information about the plugin, allow instantiation of the latest version or a particular version of the plugin - go to town
But, eventually, you use an instance of the factory to instantiate your Plugin.
This is a good place to start: What exactly is a Class Factory?, but Don Box's Essential COM book is where I learned all this stuff, a long time ago in a place far away.
Related
I have an application with client, Library and Interface as a middle layer. The classes in the Library implement the Interface.I want to call the library without having to reference it. So I dont have to do this:
IInterface myClass = new Library.MyClass();
One way is to use Unity I guess. Is there any other way? Somehow the whole idea of the Interface fades away right now.
Thanks
There are a couple of ways you can do this.
One, through the use of Dependency Inversion, as you show with Unity, and the other by writing class factories, and lastly, as you've mentioned, newing up the class instance, which is not really helpful at all :)
My own personal taste tends to Dependency Inversion, where Structuremap is my favourite IoC Container. Very easy to set up, and very easy to use, but most of the IoC Containers are very well documented.
The thing you typically end up with are something to the likes of:
IInterface myClass = myContainer.GetInstanceOf<IInterface>();
If I am right, the library is not a third party component and you can change the implementation!? If so, i would suggest to use MEF. It is part of the .Net framework and supports exactly what you want - loading components from other assemblies that are not necessarily referenced.
In your library, you have to declare the class to use in you app with an export attribute:
[Export(typeof(IInterface))] class MyClass : IInterface{ }
And in your client application, you can import the component with:
[Import(typeof(IInterface))] public IInterface myClase;
And finally you can compose all imports and exports:
var catalog = new AggregateCatalog();
// add assamby by type
catalog.Catalogs.Add(new AssemblyCatalog(typeof (AnyType).Assembly));
// add assembly by path
// this example adds all assembly in the current directory that ends with "Extension.dll".
catalog.Catalogs.Add(new DirectoryCatalog(#".", "*Extensions.dll"));
var container = new CompositionContainer(catalog);
// compose parts: MEF composes all imports and exports
container.ComposeParts(this);
It is usually being done by using Factory design pattern.
public interface IMyInterface
{
}
public class A : IMyInterface
{
internal A() // so, the user/developer won't be able to call "var a = new A()" outside of the scope of the assembly
{
}
}
public class B : IMyInterface
{
internal B()
{
}
}
public static class MyFactory
{
public static IMyInterface CreateA()
{
return new A();
}
public static IMyInterface CreateB()
{
return new B();
}
}
usage:
static void Main()
{
IMyInterface a = MyFactory.CreateA(); // instance of A
IMyInterface b = MyFactory.CreateB(); // instance of B
}
If you are creating an API, you can set the constructor of A and B to internal, so the developer won't be able to create an instance of them without using the Factory.
Note: you can use the factory to store the created instance, so it will return the same instance rather then creating a new one every single time.
I would like to create my own service with global visibility. To implement that, I followed this sample solution.
Everything goes well, I can call my service within a class, which extends from the Package abstract class, in this way:
public class ClientPackage : Package
{
private void GetGlobalServiceCallback(object sender, EventArgs args)
{
IMyGlobalService service = GetService(typeof(SMyGlobalService)) as IMyGlobalService;
}
}
Because I'm in a Package, I can easily call GetService and I can get my service. But what about if I want to get my service from a class, which is not extends the Package abstract class?
For example, I have a class, which implements an ITagger interface. If I want to get a service in this class, I have to use Package.GetGlobalService() method in this way:
var txtMgr = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager));
I tried to get my own service with the Package.GetGlobalServie(), but I always getting null. The linked sample code doesn't contain a soluiton for my problem.
May I missed something or I have a wrong scenario to get my service?
EDIT:
Okay, let's say I have to use MEF to get my service, because I can't get my service with Package.GetGlobalService().
I have a solution with 2 projects in it. One is a class library, which contains an interface like this:
public interface INamesAccessor
{
IEnumerable<string> GetNames();
}
The other project is the VSPackage (has a reference with the first project), which implements my interface as well:
[Export(typeof(INamesAccessor))]
public sealed class BitbucketExtensionPackage : Package, INamesAccessor
{
private IEnumerable<string> _names { get; set; }
public IEnumerable<string> GetNames()
{
return _names;
}
}
Let's say that if the user clicks a given menu under the Tools menu, the logic set the value of the names. Until that the _names is empty.
I would like to use the content of this _names list at my provider, like:
[Export(typeof(ITaggerProvider))]
[ContentType("text")]
[TagType(typeof(CommentTag))]
internal sealed class CommentTaggerProvider : ITaggerProvider
{
[Import]
public INamesAccessor _namesAccessor { get; set; }
public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
{
if (buffer == null)
throw new ArgumentNullException("buffer");
return buffer.Properties.GetOrCreateSingletonProperty(() => new CommentTagger(buffer, _namesAccessor )) as ITagger<T>;
}
}
I get the namesAccessor here, but every fields are null, the _names IEnumerable also.
Is there a way to force the MEF to import my accessor again when the user click to the menu button? What did I wrong?
Thank you for your answer! :)
You should use MEF to composes services for your extensions; not the old COM-based ServiceProvider stuff.
Put all of your actual code in MEF-exported classes, then invoke them from the package class using the SComponentModel service.
For more information, see my blog.
I'm working on a game that uses MVCS and has, so far, clearly separated the business logic from the view.
However, I've been having trouble with one particular piece of the puzzle.
In the game we have command classes (IPlayerCommand) that execute a specific business logic. Each command class returns a result class (PlayerCommandResult). For each PlayerCommand we have a respected visual command class (IVisualPlayerCommand) that takes the PlayerCommandResult and updates the view accordingly.
I'd like the IVisualPlayerCommand to use specific classes that inherit PlayerCommandResult in order to get the information it needs (as opposed to using object). I'd also like to make it compile-time safe (as opposed to casting it before using it). For these two reasons I made the classes use generics.
Here are the declaration of the classes:
public class PlayerCommandResult
{}
public interface IPlayerCommand<T> where T : PlayerCommandResult
{
T Execute(GameWorld world);
}
public interface IVisualPlayerComamnd<T> where T : PlayerCommandResult
{
void Play(T commandResult);
}
Here is the Move Unit command as an example:
public class MoveUnitPlayerCommand : IPlayerCommand<MoveUnitPlayerCommandResult>
{
private Unit unitToMove;
public MoveUnitPlayerCommand(Unit unit)
{
this.unitToMove = unit;
}
public MoveUnitPlayerCommandResult Execute(GameWorld world)
{
MoveUnitPlayerCommand result = new MoveUnitPlayerCommand();
// Do some changes to the world and store any information needed to the result
return result;
}
}
public class MoveUnitVisualPlayerCommand : IVisualPlayerCommand<MoveUnitPlayerCommandResult>
{
void Play(MoveUnitPlayerCommandResult commandResult)
{
// Do something visual
}
}
public class MoveUnitPlayerCommandResult : PlayerCommandResult
{
public Unit TargetUnit { get; private set; }
public Path MovePath { get; private set; }
}
So far, so good. However, I'm having a really hard time tying a IPlayerCommand to a IVisualPlayerCommand because of the use of generics:
public class CommandExecutorService
{
public void ExecuteCommand<T>(IPlayerCommand<T> command) where T : PlayerCommandResult
{
T result = command.Execute(world);
IVisualPlayerCommand<T> visualCommand = GetVisualPlayerCommand(command);
visualCommand.Play(result);
}
public IVisualPlayerCommand<T> GetVisualPlayerCommand<T>(IPlayerCommand<T> command) where T : PlayerCommandResult
{
// ?!?!?!?!?!??!?!?!??!?!
}
}
I have a feeling that what I'm trying to do is not even possible because of the way generics work in C# (as opposed to Java where I could say IVisualPlayerCommand<?>).
Could you help me figure out a way?
Any feedback for the design is welcome.
P.S. Sorry if the title doesn't reflect the question. I wasn't sure how to boil down the question in one line.
P.P.S. Which is why I also don't know if this question has been asked and answered before.
You two command classes, are served as service. To me, for this case, I would use the service locator pattern. As how to implement this pattern, you can check this link
The drawback of using template, is that, if something changes, you have to compiled it again.
Here's link which provides an example of the service locator pattern.
So for you code, you want find the corresponding instance of IVisualPlayerCommand to IPlayerCommand, so the concrete service can inherit from both interface, which it actually implements the IVisualPlayerCommand interface, while the IPlayerCommand just severs as a tag.
so the code will like this:
class MoveUnitVisualPlayerCommand: IVisualPlayerCommand, IPlayerCommand {}
services = new Dictionary<object, object>();
this.services.Add(typeof(IPlayerCommand ), new MoveUnitVisualPlayerCommand());
as how to get the service, you can refer the example.
Hope this helps.
I have an application that loads plugins. I have a plugin that has complete access to a form instance. If I have a function in a form that needs to be overridden, but is not a virtual function, is there another way to override it?
Here is a very generic example:
//Form I am modifying
public partial class MyForm : Form
{
public int myVariable1;
public int myVariable2;
//Constructor and other methods here
private void setVar(int replacementValue)
{
myVariable1 = replacementValue;
}
}
...then in a separate dll...
//My plugin
public class MyPlugin : IMyPluginBase
{
MyForm theForm; //Reference to the form in the main application
//Constructor and other methods here
private void setVar(int replacementValue)
{
theForm.myVariable2 = replacementValue;
}
}
In this example the function in the form sets 'myVariable1', but the 'setVar' function in the plugin sets 'myVariable2'.
So, the question is, in the case of this example, can I replace/override the form's 'setVar' function with the one in the plugin? Maybe with messages or reflection?
No. You cannot "replace" or overide private non-virtual methods in C#.
The C# language (and .NET runtime) don't support dynamic replacement of methods in the manner you describe. Very few languages support this capability, to my knowledge (I believe that SmallTalk and Objective-C both do).
If this is the only place in your application where you need this kind of extensibility, you can achieve it through an interface, delegate, or inhertance+virtual methods. Any of these approaches could work ... which one you choose depends on what kind of extensibility you desire.
If you expect to have many such extensibility points in your app, then you should probably take a look at the Managed Extensibility Framework (MEF). It provides a Microsoft-supported model for creating plug-in architectures using patterns and technique that work well in .NET.
If a function is not marked as virtual or part of an interface that your class implements there's exactly 0 chance you would be able to override it. No plugin, no reflection, no nothing, simply forget about it or use some other dynamic language but not C#.
The short answer to your question is no. What you can do, however, is give your form a copy of the IMyPluginBase, and have Form.setVar() call out to MyPluginBase.SetVar().
The code will look something like this:
public partial class MyForm : Form
{
public int myVariable1;
public int myVariable2;
public IMyPluginBase MyPlugin;
//Constructor and other methods here
private void setVar(int replacementValue)
{
MyPlugin.setVar(replacementValue);
//myVariable1 = replacementValue;
}
}
public class MyPlugin : IMyPluginBase
{
MyForm theForm; //Reference to the form in the main application
public void setVar(int replacementValue)
{
theForm.myVariable2 = replacementValue;
}
}
Note that setVar() will need to be defined in IMyPluginBase.
I have some classes inherit from existing Windows Controls like TextBox and DateTimePicker, ..etc
I want to add custom functionalities for these classes like (Read, Alert, ...etc)
these added functionalities are the same in all these classes
The problem is: these classes inherited from difference parents so I can't put my added functionalities in the parent class,
What's the best practice in this case:
repeat the code in each inherited
class
Use a separated class have the
functionalities as Static Methods
with parameter from an interface, implement this interface for the classes and
then pass them.
Use a separated class like the second approach but with Dynamic parameter (which added in C# 4.0)
or other !!
Thanks in advance
I'd consider option 4: composition.
First, define your set of functionality. We'll assume that your partial list is exclusive, so "Read" and "Alert."
Second, create a single class that implements this functionality, something like MyCommonControlBehaviors. I'd prefer this implementation not be static if possible, though, it may be generic.
public MyCommonControlBehaviors
{
public Whatever Read() { /* ... */ }
public void Alert() {}
}
Third, use composition to add an instance of this class to each of your custom control types and expose that functionality through your custom control:
public class MyCustomControl
{
private MyCommonControlBehaviors common; // Composition
public Whatever Read() { return this.common.Read(); }
public void Alert() { this.common.Alert(); }
}
Depending on specifics, you can get creative to the degree necessary. E.g., perhaps your custom behaviors need to interact with private control data. In that case, make your control implement a common ICommonBehaviorHost interface that your common behaviors need. Then pass the control into the behavior class on construction as an instance of ICommonBehaviorHost:
public interface ICommonBehaviorHost
{
void Notify();
}
public class MyCommonControlBehaviors
{
ICommonBehaviorHost hst = null;
public MyCommonControlBehaviors(ICommonBehaviorHost host)
{
this.hst = host;
}
public void Alert() { this.hst.Notify(); } // Calls back into the hosting control
// ...
}
public class MyCustomControl : ICommonBehaviorHost
{
private MyCommonControlBehaviors common = null;
public MyCustomControl() { common = new MyCommonControlBehaviors(this); }
public Whatever Read() { return this.common.Read(); }
public void Alert() { this.common.Alert(); }
void ICommonBehaviorHost.Notify() { /* called by this.common */ }
}
Use Composition instead of Inheritence!
If you must, what I would probably do is create extension methods for each class and then reference the actual coded needed for these in some other object all the extension methods can call.
This way the code isn't duplicated, and the extension methods make it look like the methods should be in the object.
It's the same essentially by creating a static method and doing: Functions.DoSomething(my_Object);
But I always like: my_Object.DoSomething() better in an OO language.
I would suggest defining an interface for the behaviors, and then (to keep from repeating yourself) create extension methods on that interface definition for your shared methods. (Kinda like your second option, only with extension methods instead of totally static methods).