mercredi 1 novembre 2017

How to properly build plug-in paddern

I want to build a plug-in pattern and at first: could you tell me how to compile my plug-in before build the main project, with Pre-Build-Event?

Also could you tell me how to properly build up a plug-in paddern.

Until now I have:

public static class TechnologyPlugInLoader
{
    public static PlugInUserInterface LoadTechnology()
    {
        var plugInPath = Directory.GetFiles(CodingTool.Properties.Settings.Default.TechnologyPath).FirstOrDefault(path => Path.GetExtension(path) == ".exe"
            && Path.GetFileName(path) != Assembly.GetExecutingAssembly().ManifestModule.Name);

        var plugIn = Assembly.LoadFile(Path.GetFullPath(plugInPath));
        var type = plugIn.GetTypes().SingleOrDefault(t => t.Name == "MainWindow");

        if (type == null)
            return default(PlugInUserInterface);

        return (PlugInUserInterface)Activator.CreateInstance(type);
    }
}

I´m not sure about the Type-Loading:

var type = plugIn.GetTypes().SingleOrDefault(t => t.Name == "MainWindow");

Is there a common way to do that? The biggest problem is the name MainWindow which means all my plug-in´s have to have this class. Also a problem seems to me the way I load the plug-in:

... path => Path.GetExtension(path) == ".exe"
            && Path.GetFileName(path) != Assembly.GetExecutingAssembly().ManifestModule.Name;

This say´s that my plug-in has to be an execution and should be the first in the plug-in folder, preferably the only one beside the main execution.

My plug-in interface looks like:

public interface PlugInUserInterface
{
    FrameworkElement DefaultWindowGrid { get; }
    Dictionary<string, RoutedEventHandler> Features { get; }
}

and is used like:

public MainWindow()
    {
        var plugIn = TechnologyPlugInLoader.LoadTechnology();

        InitializeComponent();

        TechnologyGrid.Children.Add(plugIn.DefaultWindowGrid);

        foreach (var feature in plugIn.Features)
        {
            var menuItem = new MenuItem();
            menuItem.Header = feature.Key;
            menuItem.Click += feature.Value;

            ExtraMenuItem.Items.Add(menuItem);
        }

        InitializeComponent();
        DataContext = this;
    }

XAML Code:

<controls:MetroWindow x:Class="SomeNamespace.MainWindow"
    xmlns="http://ift.tt/o66D3f"
    xmlns:x="http://ift.tt/mPTqtT"
    xmlns:controls="http://ift.tt/OTZSAn" 
    GlowBrush="SteelBlue"
    WindowStartupLocation="CenterScreen"
    Height="350" Width="525">
<DockPanel>
    <Menu DockPanel.Dock="Top">
        <MenuItem Header="Extras" Name="ExtraMenuItem">
        </MenuItem>
    </Menu>
    <Grid Name="TechnologyGrid">

    </Grid>
</DockPanel>

could you help me to do it properly. Thanks in advance :-)





Aucun commentaire:

Enregistrer un commentaire