2

i'm using the desktop library of prism.

what i want is to get modules in a directory and then, run them.

I do like that:

DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
catalog.ModulePath = @"C:\Users\Raph\Documents\Visual Studio 2010\Projects\LibraryLoad\LibraryLoad\Modules";

I checked, the modules are loaded in the catalog. Example of a module:

public class SendEmailClass : IModule
    {
        public void SendEmail()
        {
            MailMessage mail = new MailMessage();
            mail.From = new MailAddress("**", "moi");
            mail.Subject = "Report"; //manage generated subject

            mail.To.Add("***");

            System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("smtp.gmail.com");
            smtp.Port = 57;
            smtp.EnableSsl = true; //depending of the smtp server
            NetworkCredential cred = new NetworkCredential("***", "***");
            smtp.Credentials = cred;
            smtp.Send(mail);
        }

        public void Initialize()
        {
            SendEmail();
        }
    }

But then i want to run them (launch their Initialize()) but i don't find it. I want to run the whole catalog. someone has an idea ? I tried catalog.Initialize(), catalog.Validate() or catalog.Load()

raphael
  • 53
  • 1
  • 4

3 Answers3

2

Your code looks correct, I was under the impression that you had to override the GetModuleCatalog() method in your Bootstrapper class in order to do this. Here is a working example of a pretty straight forward Bootstrapper that loads modules from a modules directory.

public class Bootstrapper : UnityBootstrapper
{
    private const string MODULE_FOLDER = @".\modules";

    protected override IModuleCatalog GetModuleCatalog()
    {
        DirectoryModuleCatalog catalog = new DirectoryModuleCatalog() { ModulePath = MODULE_FOLDER };
        return catalog;
    }
}

Update

It is probably possible to not use a bootstrapper and load your modules, but I do not see why you would not take advantage of the UnityBootstrapper class, it does the work for you.

Bootstrapper bootStrapper = new Bootstrapper();
bootStrapper.Run();

Your modules will be loaded. I myself have never done this without using the bootstrapper because it is very straightforward.

jsmith
  • 7,198
  • 6
  • 42
  • 59
  • is it possible to not use a bootstrapper ? actually i don't use any shell, i will use it in windows service (no gui). – raphael Sep 27 '10 at 16:01
1

As jsmith said, the default bootstrapper provides the heavy lifting for the configuration that you would otherwise perform yourself. If you don't have a Shell, simply create a custom bootstrapper that skips over that part.

In case you don't want to use a bootstrapper by any means, you can just instantiate the ModuleManager class, passing the ModulesCatalog as one of the parameters and call the ModuleManager's Run method.

As I said before, the above is done by the bootstrapper for you. I hope this helps.

Thanks, Damian

Damian Schenkelman
  • 3,505
  • 1
  • 15
  • 19
  • Thank you for your answer. But if I want to load for example my modules every 15 minutes (with a timer), i think i cant use the bootstrapper because it loads only at the start of the application, right ? – raphael Sep 28 '10 at 13:11
  • @raphael: Modules are not supposed to be loaded many times. They are meant to be loaded onyl once (as loading the assembly in the appdomain) an their components can be reused. More info here: http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=59827 http://compositewpf.codeplex.com/Thread/View.aspx?ThreadId=59040 – Damian Schenkelman Sep 28 '10 at 13:13
  • ok ! so i understand well: if i add a new module (dll) in my directory "modules", i need to restart the application to consider this new module ? – raphael Sep 28 '10 at 13:20
  • Not necessarilly. If you want to load the module while the application is running you can use on-demand module loading (http://msdn.microsoft.com/en-us/library/ff921071%28PandP.20%29.aspx). Using a FileSystemWatcher and having the module registered in the catalog should allow you to achieve your goals. Prism does not provide this functionality by default (watching a directory and automatically loading modules when the directory changes), but with a couple of changes to the directory catalog module loader you should be fine. – Damian Schenkelman Sep 28 '10 at 13:36
0

How are you bootstrapping your application? Have you created a bootstrapper class? It is the bootstrapper that initializes all of your modules.

This is an example of a bootstrapper class I made.

public class ApplicationBootstrapper : UnityBootstrapper
{
    // Here is where you create your module catalog
    protected override IModuleCatalog GetModuleCatalog()
    {
        DirectoryModuleCatalog catalog = new DirectoryModuleCatalog();
        catalog.ModulePath = @"C:\Users\Raph\Documents\Visual Studio 2010\Projects\LibraryLoad\LibraryLoad\Modules";

        return catalog;
    }

    // Here is where you create your user interface shell.
    protected override DependencyObject CreateShell()
    {
        Container.RegisterInstance<IApplicationSettings>(new ApplicationSettings());

        Shell shell = Container.Resolve<Shell>();

        if (shell != null)
            shell.Show();

        return shell;
    }

}

Then in your App.xaml file's OnStartup, you run your bootstrapper and it will call initialize on all of your modules.

protected override void OnStartup(StartupEventArgs e)
{
    ApplicationBootstrapper bootstrapper = new ApplicationBootstrapper();
    bootstrapper.Run();
}

This example uses the Unity bootstrapper, all you need is the Unity platform which is available side-by-side with Prism.

Jordan
  • 9,642
  • 10
  • 71
  • 141