¿Hacia dónde se dirige el Marco de Extensibilidad para.NET?
mef (9)
No es una inyección de contenedor de control. Es un marco de soporte de complemento.
¿Alguien ha trabajado mucho con el Marco de Extensibilidad Administrada (MEF) de Microsoft? Suena como si tratara de ser todo para todas las personas: ¡es un administrador adicional! ¡Es pato escribiendo! Me pregunto si alguien tiene una experiencia con eso, positiva o negativa.
Actualmente estamos planeando utilizar una implementación de IoC genérica ala MvcContrib para nuestro próximo gran proyecto. ¿Deberíamos lanzar MEF en la mezcla?
Diría que dado que se va a colgar del espacio de nombres de ''Sistema'' en .NET Framework 4.0, no podría ir demasiado mal. Será interesante ver cómo evoluciona el MEF y qué influencia tiene Hamilton Verissimo (Castle) en la dirección del MEF.
Si grazna como un pato, podría ser parte de la manada actual de contenedores IoC ...
Andy, creo que Glenn Block responde muchas de estas preguntas (naturales) como estas en este hilo del Foro MSDN MEF:
Comparación de CompositionContainer con contenedores tradicionales de IoC .
Hasta cierto punto, la respuesta de Artem anterior es correcta en relación con la intención principal detrás de MEF, que es la extensibilidad y no la composición. Si lo que más le interesa es la composición, use uno de los otros sospechosos habituales de IoC. Si, por otro lado, lo que más le preocupa es la extensibilidad, la introducción de catálogos, partes, etiquetado de metadatos, mecanografía de patos y carga diferida constituyen algunas posibilidades interesantes. Además, Krzysztof Cwalina toma una oportunidad aquí para explicar cómo MEF y System.Addins se relacionan entre sí.
Duck typing no se enviará en V1 aunque esté en la caída actual. En una caída futura, lo reemplazaremos con un mecanismo adaptador enchufable en el que uno podría enganchar un mecanismo de tipado de pato. La razón por la que analizamos el tipado de patos es para abordar los escenarios de versiones. Con Duck Typing puede eliminar las referencias compartidas entre exportadores e importadores, lo que permite que varias versiones de un contrato vivan una al lado de la otra.
Sobre la cuestión de la seguridad de Andy para las extensiones que MEF carga (lo siento, aún no tengo suficientes puntos :)), el lugar para abordar esto está en un catálogo. Los catálogos MEF son completamente conectables, por lo que puede escribir un catálogo personalizado que valide las claves de ensamblaje, etc. antes de cargar. Incluso podría usar CAS si así lo desea. Estamos buscando proporcionar anzuelos que le permitan hacer esto sin tener que escribir un catálogo. Sin embargo, la fuente de los catálogos actuales está disponible gratuitamente. Sospecho que el mínimo es alguien (tal vez en nuestro equipo) implementará uno y lo lanzará en un proyecto de extensión / contribución en CodePlex.
Discusión más detallada sobre esto en este post y los comentarios
http://mikehadlow.blogspot.com/2008/09/managed-extensibility-framework-why.html
Ayende también tiene una muy buena redacción aquí: http://ayende.com/Blog/archive/2008/09/25/the-managed-extensibility-framework.aspx
Esta publicación hace referencia a Managed Extensibility Framework Preview 2.
Por lo tanto, tuve una carrera a través de MEF y escribí un rápido "Hola mundo", que se presenta a continuación. Debo decir que fue totalmente fácil sumergirse y comprender. El sistema de catálogo es excelente y hace que la extensión del MEF sea muy sencilla. Es trivial señalarlo en un directorio de complementos y dejar que se encargue del resto. La herencia de MEF a lo largo del Prisma ciertamente se muestra, pero creo que sería extraño si no fuera así, dado que ambos marcos tienen que ver con la composición.
Creo que lo que más me gusta es la "magia" de _container.Compose (). Si observas en la clase HelloMEF, verás que el campo de saludos nunca se inicializa con ninguno de los códigos, lo cual es gracioso. Creo que prefiero la manera en que funcionan los contenedores IoC, donde explícitamente le pides al contenedor que construya un objeto para ti. Me pregunto si algún tipo de inicializador genérico "Nada" o "Vacío" podría estar en orden. es decir
private IGreetings greetings = CompositionServices.Empty<IGreetings>();
Eso al menos llena el objeto con "algo" hasta que el código de composición del contenedor se ejecuta para llenarlo con un "algo" real. No sé, huele un poco a las palabras clave Empty o Nothing de Visual Basic, que no me gustó. Si alguien más tiene algunas ideas sobre esto, me gustaría escucharlas. Tal vez es algo que solo necesito superar. Está marcado con un gran atributo [Importar] gordo, por lo que no es como si fuera un completo misterio ni nada.
Controlar la duración del objeto no es obvio, pero todo es un singleton por defecto a menos que agregue un atributo [CompositionOptions] a la clase exportada. Eso permite que usted especifique Factory o Singleton. Sería bueno ver a Pooled agregado a esta lista en algún momento.
No tengo muy claro cómo funcionan las funciones de tipado de patos. Parece más una inyección de metadatos en la creación de objetos que en la tipa de patos. Y parece que solo puedes agregar un pato adicional. Pero como dije, no tengo muy claro cómo funcionan estas funciones todavía. Espero poder volver y llenar esto más tarde.
Creo que sería una buena idea duplicar las DLL cargadas por DirectoryPartCatalog. En este momento, los archivos DLL están bloqueados una vez que MEF los atrapa. Esto también te permitirá agregar un vigilante de directorio y capturar complementos actualizados. Eso sería muy amable...
Finalmente, estoy preocupado sobre cuán confiables son las DLL de complementos y cómo, o si, MEF se comportará en un entorno de confianza parcial. Sospecho que las aplicaciones que usan MEF requerirán plena confianza. También podría ser prudente cargar los complementos en su propio Dominio de aplicación. Sé que huele un poco a System.AddIn, pero permitiría una separación muy clara entre los complementos del usuario y los complementos del sistema.
De acuerdo, suficiente charlatanería. Aquí está Hello World en MEF y C #. ¡Disfrutar!
using System;
using System.ComponentModel.Composition;
using System.Reflection;
namespace HelloMEF
{
public interface IGreetings
{
void Hello();
}
[Export(typeof(IGreetings))]
public class Greetings : IGreetings
{
public void Hello()
{
Console.WriteLine("Hello world!");
}
}
class HelloMEF : IDisposable
{
private readonly CompositionContainer _container;
[Import(typeof(IGreetings))]
private IGreetings greetings = null;
public HelloMEF()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
_container = new CompositionContainer(catalog);
var batch = new CompositionBatch();
batch.AddPart(this);
container.Compose(batch);
}
public void Run()
{
greetings.Hello();
}
public void Dispose()
{
_container.Dispose();
}
static void Main()
{
using (var helloMef = new HelloMEF())
helloMef.Run();
}
}
}
No pretendemos que MEF sea un CoC de propósito general. La mejor manera de pensar sobre los aspectos de IoC de MEF es un detalle de implementación. Usamos IoC como un patrón porque es una gran manera de abordar los problemas que estamos tratando de resolver.
MEF se centra en la extensibilidad. Cuando piensas en MEF, míralo como una inversión para llevar adelante nuestra plataforma. Nuestros productos futuros y la plataforma aprovecharán MEF como un mecanismo estándar para agregar extensibilidad. Los productos y marcos de terceros también podrán aprovechar este mismo mecanismo. El "usuario" promedio de MEF creará componentes que MEF consumirá y no consumirá directamente MEF dentro de sus aplicaciones.
Imagínese que cuando quiera ampliar nuestra plataforma en el futuro, suelte un dll en la carpeta bin y listo. La aplicación MEF habilitada se ilumina con la nueva extensión. Esa es la visión para MEF.