Using MEF inside a class library - mef

OK, so inside a class library, is it a good idea NOT to use MEF?
Here is an example:
ISomeInterface
5 Implementations of ISomeInterface
Once class that imports all ISomeInterface and uses them.
Again, this is all inside a single dll. Since it is in a DLL, there is no bootstrapping of MEF to create the catalog, and it seems a bit much to build a catalog just to use it once.
Am just learning MEF and how to use it.
Greg

After reading up a bit more on this, it looks like there is no reason that MEF can't be used inside a DLL for it's own parts creation. When I asked this question, I was thinking that the Importing would be mainly inside a Main() or App() type of function to compose the entire app. But if composing needs to be done on a major part that gets exported to the app, it can still use MEF to compose itself in the constructor, like this:
//An aggregate catalog that combines multiple catalogs
var catalog = new AggregateCatalog();
//Adds all the parts found in the same assembly as the Program class
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Program).Assembly));
//Create the CompositionContainer with the parts in the catalog
_container = new CompositionContainer(catalog);
//Fill the imports of this object
try
{
this._container.ComposeParts(this);
}
catch (CompositionException compositionException)
{
}

Related

Is it possible to implement a module that is not a WPF module (a standard class library, no screens)?

I am developing a modular WPF application with Prism in .Net Core 5.0 (using MVVM, DryIoc) and I would like to have a module that is not a WPF module, i.e., a module with functionality that can be used by any other module. I don't want any project reference, because I want to keep the loosely coupled idea of the modules.
My first question is: is it conceptually correct? Or is it mandatory that a module has a screen? I guess it should be ok.
The second and more important (for me) is, what would be the best way to create the instance?
This is the project (I know I should review the names in this project):
HotfixSearcher is the main class, the one I need to get instantiated. In this class, for example, I subscribe to some events.
And this is the class that implements the IModule interface (the module class):
namespace SearchHotfix.Library
{
public class HotfixSearcherModule : IModule
{
public HotfixSearcherModule()
{
}
public void OnInitialized(IContainerProvider containerProvider)
{
//Create Searcher instance
var searcher = containerProvider.Resolve<IHotfixSearcher>();
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IHotfixSearcher, HotfixSearcher>();
}
}
}
That is the only way I found to get the class instantiated, but I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
For modules that have screens, the instances get created when navigating to them using the RequestNavigate method:
_regionManager.RequestNavigate(RegionNames.ContentRegion, "ContentView");
But since this is only a library with no screens, I can't find any other way to get this instantiated.
According to Prism documentation, subscribing to an event shoud be enough but I tried doing that from within my main class HotfixSearcher but it does not work (breakpoints on constructor or on the event handler of the event to which I subscribe are never hit).
When I do this way, instead, the instance is created, I hit the constructor breakpoint, and obviously the instance is subscribed to the event since it is done in the constructor.
To sum up, is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
Thanks in advance!
Or is it mandatory that a module has a screen?
No, of course not, modules have nothing to do with views or view models. They are just a set of registrations with the container.
what would be the best way to create the instance?
Let the container do the work. Normally, you have (at least) one assembly that only contains public interfaces (and the associated enums), but no modules. You reference that from the module and register the module's implementations of the relevant interfaces withing the module's Initialize method. Some other module (or the main app) can then have classes that get the interfaces as constructor parameters, and the container will resolve (i.e. create) the concrete types registered in the module, although they are internal or even private and completely unknown outside the module.
This is as loose a coupling as it gets if you don't want to sacrifice strong typing.
is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
You can skip the var searcher = part :-) But if the HotfixSearcher is never injected anywhere, it won't be created unless you do it yourself. OnInitialized is the perfect spot for this, because it runs after all modules had their chance to RegisterTypes so all dependencies should be registered.
If HotfixSearcher is not meant to be injected, you can also drop IHotfixSearcher and resolve HotfixSearcher directly:
public void OnInitialized(IContainerProvider containerProvider)
{
containerProvider.Resolve<HotfixSearcher>();
}
I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
It is used, I suppose, although not through calling one of its methods. It's used by sending it an event. That's just fine. Think of it like Task.Run - it's fine for the task to exist in seeming isolation, too.

How to add new class and autoload in zend framework

I am new on Zend framework and using first time it. I am looking for simple basic tutorials which I can read in very short time. I also stuck on if I want to add new class in Zend library. And it should also auto load when I make any new controller.
Please give your opinions if you have.
Regards,
This helped me At the beginning:
http://www.zendcasts.com/
http://devzone.zend.com/search/results?q=autoload (just search)
As autoload your class, This is the my way:
Create folder 'My' into library/
in it create folder 'Utils' and in Utils file 'Utils.php' so the path is library/My/Utils/Utils.php
For this path You must call class: class My_Utils_Utils{ ... }
and in configs/application.ini Put
appnamespace = "Application"
autoloaderNamespaces.my = "My_"
Then you can use namespace My_ and class My_Utils_Utils
In controller: $test = new My_Utils_Utils();
I am looking for simple basic tutorials
Here are a few tutorials I found while googling:
Official quickstart tutorial
A great book by frequent ZF-contributer PadrĂ¡ic Brady: Survive the deep end!
http://akrabat.com/zend-framework-tutorial/
Page with different tutorials: ZFTutorials.com
I also stuck on if I want to add new class in Zend library
You should not add new classes to the library per se, but instead create your own library or add classes in the "models"-folder/folders (if you use the modular project layout). Autoloading is achieved by utilizing Zend_Loader_Autoloader and its subclasses. As long as you follow the PEAR convention, i.e. if you have a class MyLib_Database_Table, then it should be inside the folder MyLib/Database, and the filename should be Table.php. (also make sure that the parent folder of MyLib is on the project include path.
To autoload simply use new MyLib_Database_Table, and the autoloader will load the class behind the scenes if necessary. Since 1.10 (I think), the autoloader also fully support PHP 5.3 namespaces. I.e:
// Filepath: lib\MyLib\Database\Table.php
namespace MyLib\Database;
class Table {
}
will work with the same folder structure. Code example:
use MyLib\Database\Table;
class IndexController extends Zend_Controller_Action
{
public function indexAction ()
{
$myTable = new Table();
}
}
auto load when I make any new controller
I'm not quite sure what you mean here. ZF does not have any dependency injection setup per default. But you can instantiate your classes without requiring them first if that's what you mean.

How can I add an existing instance to a MEF catalog?

I have an object instance, and I want to end up with a MEF catalog that contains that object instance, exported as a specific interface type. How can I do this?
TypeCatalog doesn't seem workable here, because (a) it creates a new instance instead of using an existing one, and (b) it requires the type to have an [Export] attribute. In my case, the instance comes from MEF's metadata system, so MEF creates the underlying type and I can't add attributes to it.
As far as I can tell, the usual advice is, if you've got an existing instance, you should add it to the container (e.g. via CompositionBatch), not to the catalog. But when I add this instance, I'm also adding an entire AssemblyCatalog worth of types, all in the same operation. I'll also want to be able to remove all of these types later. It makes more sense to me to bundle everything into an AggregateCatalog. That way, I can add both the assembly and the instance in one atomic operation, and I can remove them all again the same way.
For example:
// Bootstrapper code to initialize MEF:
public void Configure() {
_selectedGameCatalog = new AggregateCatalog();
var globalCatalog = new AggregateCatalog(_selectedGameCatalog);
_container = new CompositionContainer(globalCatalog);
// ... more MEF initialization ...
}
// Sometime later, I want to add more stuff to the MEF ecosystem:
public void SelectGame(Lazy<Game, IGameMetadata> entry) {
var newCatalog = new AggregateCatalog();
// Make the assembly available to import:
newCatalog.Catalogs.Add(new AssemblyCatalog(entry.Value.GetType().Assembly));
// I also want the metadata to be available to import:
IGameMetadata metadata = entry.Metadata;
newCatalog.Catalogs.Add(MakeCatalogFromInstance<IGameMetadata>(metadata));
// Replace whatever game was selected before:
_selectedGameCatalog.Catalogs.Clear();
_selectedGameCatalog.Catalogs.Add(newCatalog);
}
The part I don't know how to do is "MakeCatalogFromInstance". How can I create a catalog that contains an existing instance (registered as a specific type)?
Or, alternatively, if I'm going about this all wrong, is there a better way to plug an entire catalog and an existing instance all into MEF at the same time, with the ability to unplug them all again later and replace them with something else?
I think it's probably best to add the types to the catalog and then add the instance to the container.
Catalogs contain part definitions. Part definitions are used to create parts. (The types for this are ComposablePartDefinition and ComposablePart.) So you could theoretically write your own catalog and a part definition that always returned a part corresponding to the instance when CreatePart was called. But catalogs weren't really designed to be used this way.
For prosperity...
MEF devivides the chores of what type info is to be used (catalog) from the actual running object instances (container). To me it is a logical descicion, especially when you setup a more complex MEF environment in your application.
If you want the ability to 'change' containers on the fly, I would suggest you try to use hierarchical containers. The root catalog/container is filled with static types and any of the child containers can be filled with each specific set of meta types you need for your game.
Hope it helps,
Marc

MEF: what is the role, lifetime and knowledge of the 'container'?

i'm playing with MEF and in the example i see this code ( i call it the MEF compose code):
var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly());
var container = new CompositionContainer(catalog);
container.ComposeParts();
In most examples this is done in the same source file as the Startup Program class lives, as well as all of the other interfaces and classes.
Now i want to use the MEF, but i wonder what this container does. As far as i guessed it does the export / import mapping, but what if i have this code (from a windows forms app:
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
and in that Form1 i want to create an object of type Auditer (which has a property of type ILogger marked import, and i have a class implementing ILogger marked export).
Do i have to place the MEF compose code in the void Main(), in the Load event of Form1, or in the constructor of the Auditer class?
I only get it to work when i put it (the MEF compose code) in the constructor of the Auditer class, but the examples i read somehow give me the idea that you only have to call the compose code once.
The CompositionContainer is the class that actually composes your parts in MEF.
When you want to use MEF, you need to always compose the part that's attributed with the import definitions. If you have a property in Form1 that's marked with [Import(typeof(ILogger))], at some point, you'll need to compose your Form1 instance.
The CompositionContainer is the class that actually performs this composition. It finds the appropriate exported ILogger based off the Catalog(s) contained within the container, and constructs types, matches exports to the imports, etc.
The reason that the MEF samples only "compose" one time is that, often, with DI, you'll have a single instance of the container constructed and setup at the beginning of the application, and it will compose your "main" window. All other classes will be composed automatically if they're being used as part of the main window. (For example, if Form1 composes an ILogger, but your ILogger implementation has an [Import] of it's own, it too will get composed in that pass.)
That being said, there is no fixed rule that specifies you can't compose more than once. In WPF and Silverlight, for example, it's frequent that MEF can't construct your object, which means it can't automatically compose your object for you. In these situations, a common pattern is to use the CompositionInitializer (in the box in Silverlight, not in the desktop) to have parts compose themselves, based off a static catalog. I recently blogged about this approach for WPF.
With Windows Forms, this may be less necessary, since there isn't a third party product (the XAML parser) constructing your types. However, you could still use this same approach, if you so choose.

Library assembly IoC setup

I am working in a project that has two main parts: a class library assembly and the main application. Both are using Castle Windsor for IoC and both manually setup their list of of components in code (to aid refactoring and prevent the need for a config file). Currently the main application has code like this:
public static void Main()
{
// Perform library IoC setup
LibraryComponent.Init();
// Perform application IoC setup
IoC.Register<IXyz, Abc>("abc");
// etc, etc, ...
// Start the application code ...
}
However the call to initialise the library doesn't seem like a good solution. What is the best way to setup a class library that uses an IoC container to decouple its internal components?
Edit:
Lusid proposed using a static method on each public component in the library that would in turn make the call to initialise. One possible way to make this a bit nicer would be to use something like PostSharp to do this in an aspect-oriented way. However I was hoping for something a bit more elegant ;-)
Lusid also proposed using the AppDomain.AssemblyLoad event to perform custom steps at load time, however I am really after a way to avoid the client assembly from requiring any setup code.
Thanks!
I'm not sure if I'm understanding exactly the problem you are trying to solve, but my first guess is that you are looking for a way to decouple the need to call the Init method from your main application.
One method I've used in the past is a static constructor on a static class in the class library:
static public class LibraryComponent {
static LibraryComponent() {
Init();
}
}
If you have multiple class libraries, and would like a quick and dirty way of evaluating all of them as they are loaded, here's a (kinda hairy) way:
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);
}
static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
IEnumerable<Type> types = args.LoadedAssembly.GetTypes()
.Where(t => typeof(IMyModuleInterface).IsAssignableFrom(t));
foreach (Type t in types)
{
doSomethingWithType(t);
}
}
The Where clause could be anything you want, of course. The code above would find any class deriving from IMyModuleInterface in each assembly that gets loaded into the current AppDomain, and then I can do something with it, whether it be registering dependencies, maintaining an internal list, whatever.
Might not be exactly what you are looking for, but hopefully it helps in some way.
You could have a registration module. Basically LibraryComponent.Init() function takes an IRegistrar to wire everything up.
The IRegistrar could basically have a function Register(Type interface, Type implementation). The implimentor would map that function back to their IOC container.
The downside is that you can't rely on anything specific to the container your using.
Castle Windsor actually has a concept called facilities that are basically just ways of wrapping standardised pieces of configuration. In this model, you would simply add the two facilities to the container and they would do the work.
Of course, this wouldn't really be better than calling a library routine to do the work unless you configured the facilities in a configuration file (consider binsor). If you are really allergic to configuration files, your current solution is probably the best.