Quantcast
Channel: Managed Extensibility Framework
Viewing all 265 articles
Browse latest View live

New Post: Strongly typed metadata

$
0
0

Hi all,

I'm relatively new to MEF, so please forgive me for poor code or if this is blindingly obvious.

I'm using the System.Composition namespace from the MEF for web and Windows Store apps NuGet package in a new ASP.NET MVC4 project.

I've read that in MEF2 you no longer use Lazy<IExtension, IExtensionMetadata>, but now you must provide a concrete type for the metadata view and use ExportFactory<> instead of Lazy<>.

However, I can't find any examples of how this should all work - just a few mentions of using a concrete type instead of an interface.

I've tried a few things, but keep getting the following exception - "Export metadata for 'AccountID' is missing and no default value was supplied".

My code...

Creating the container (in Global.asax or App_Start folder):

// Get assemblies that will be providing imports and exportsvar assemblies = GetAssemblies();

// Get conventions that will be used to find imports and exportsvar conventions = GetConventions();

var container = new ContainerConfiguration().WithAssemblies(assemblies, conventions).CreateContainer();

// Create and apply a MefControllerFactory so controllers can be composed
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(container));

GetConventions() method:

privatestatic ConventionBuilder GetConventions()
{
    var conventionBuilder = new ConventionBuilder();
    conventionBuilder.ForTypesDerivedFrom<IController>().Export();

    conventionBuilder.ForTypesDerivedFrom<IExtension>().Export<IExtension>();
    conventionBuilder.ForTypesMatching(t => t.Namespace != null&& t.Namespace.EndsWith(".Parts")).Export().ExportInterfaces();

    return conventionBuilder;
}

IExtension.cs: 

publicinterface IExtension
{
    void DoWork();
}

ExtensionMetadata.cs: 

publicclass ExtensionMetadata
{
    publicint AccountID { get; set; }
}

ExtensionA.cs (same as ExtensionB.cs): 

publicvoid DoWork()
{
    System.Diagnostics.Debug.WriteLine("ExtensionA doing work..");
}

ExtensionManager.cs: 

publicclass ExtensionManager
{       
    private IEnumerable<ExportFactory<IExtension, ExtensionMetadata>> _extensions;

    public ExtensionManager(IEnumerable<ExportFactory<IExtension, ExtensionMetadata>> extensions)
    {
        _extensions = extensions;
    }

    publicvoid DoWork(int accountID)
    {
        foreach (var extension in _extensions)
        {
            if (extension.Metadata.AccountID == accountID)
            {
                extension.DoWork();
            }                   
        }           
    }
}

I think I'm missing something quite major here. Basically I want to lazily import all Extensions, check their metadata and if a condition is fulfilled have that extension do something.

Am I missing some attributes somewhere? Are they still required in MEF2?

Would really appreciate your help or any links to sample code / tutorials that cover this scenario.

I've posted this question on StackOverflow, but so far have not had any replies so am also posting here (hope that's ok?).

Many thanks!


New Post: Strongly typed metadata

$
0
0

I think I've worked it out after reading this SO question.

I created a Metadata Attribute:

[MetadataAttribute]
publicclass ExtensionMetadataAttribute : ExportAttribute, IExtensionMetadata
{
	publicint ID { get; set; }

	public ExtensionMetadataAttribute(int id) : base(typeof (IExtension))
	{
		ID = id;
	}
}

Then modified ExtensionA.cs:

[ExtensionMetadata(1)]
publicclass ExtensionA : IExtension
{
	publicvoid DoWork()
	{
		System.Diagnostics.Debug.WriteLine("ExtensionA doing work..");
	}
}

And now ExtensionManager.cs looks like this:

publicclass ExtensionManager : IExtensionManager
{
	privatereadonly IEnumerable<ExportFactory<IExtension, ExtensionMetadata>> _extensions;

	public ExtensionManager(IEnumerable<ExportFactory<IExtension, ExtensionMetadata>> extensions)
	{
		_extensions = extensions;
	}

	publicvoid DoWork(int extensionID)
	{
		foreach (var extension in _extensions)
		{
			if (extension.Metadata.ID == extensionID)
			{
				using (var foo = extension.CreateExport())
				{
					foo.Value.DoWork();
				}
			}
		}
	}
}

This seems to do the trick, but I would still be interested in your feed back re best practices, performance issues etc.

Thanks!

New Post: Import visibility with MEFX

$
0
0

Hi again,

Nobody can explain this?

Is this behaviour expected?

Thanks for an answer
Olivier Monney

New Post: Import visibility with MEFX

$
0
0

Hi Oliver,

In MEF's discovery model, only types that have exports are considered "parts". This is because although MEF could find imports on types like the one above, there's no way for a composition container to create instances of them, so instead it ignores them until a method like SatisfyImports() called.

MEFX is only a thin layer over MEF's regular discovery/catalog system, so it maintains the same behaviour. What you're seeing here is expected.

What situation are you aiming to detect, using MEFX in this scenario?

Hope this helps,
Nick 

New Post: Correct behavior

$
0
0

Hi Martin,

Any chance of some code illustrating your scenario here?

Cheers,

Nick

New Post: Import visibility with MEFX

$
0
0

Hi,

Thanks for your anwser.

The situation I'm aiming to detect is to tell MEFX which classes are initiating a chain composition. In the small example it would be "MyClass"

I just wanted to list my imports and see if any exports were available to satisfy them. But it appears that MEFX would need, as MEF does, to call SatisfyImports() to have the composition begining.
I understand much better how MEFX behaves.

Olivier

New Post: Removal of System.Composition.Web.Mvc and the support for .NET 4.0

$
0
0

I am also looking forward MEF 2.0 to be supported in .NET 4.0.

New Comment on "Microsoft.Composition FAQ"

$
0
0
Can I Use MEF in my WinForm applications?

New Post: Cannot call SatisfyImports on a object of type 'xx' because it is marked with one or more ExportAttributes.

$
0
0

You only need to call  SatisfyImports once then use the "GetExportedValue" to new up the types from the container

  Container.GetExportedValue<ICountries>();



I know this is quite an old post but its nice to have questions wrapped up.

Commented Issue: If a base class has an import that fails the exception does not give the right reason [8492]

$
0
0
In the code below the test fails until you un-comment on the line "var typeCatalog = new TypeCatalog(typeof(Foo));//, typeof(Bar));". Then the test works.

FooImporter is a class that imports Foo. The Foo has a base class FooBase. FooBase has an import on IBar. The contract IBar is not possible to satisfy without the type Bar that exports the contract IBar.

If I try to satisfy imports on Foo without the container knowing Bar the error reported is not that an IBar Export is missing. The error is that IFoo is missing which it technically is not. It is present but has a child that is missing.

On the other hand if you try to satisfy imports on the Foo class direct the error shows that IBar is missing (second test).

As I see it there is a break in the error reporting causing the erroneous assumption that IFoo is missing when it is IBar that is missing. But only when Foo is not the root of the graph satisfied by MEF.

Cheers,

M.

[TestClass]
public class MEFBadBaseImportTests
{
[TestMethod]
public void Bad_base_class_messes_up_the_error_message()
{
var typeCatalog = new TypeCatalog(typeof(Foo));//, typeof(Bar));
var compositionContainer = new CompositionContainer(typeCatalog);

var fooImporter = new FooImporter();

try
{
compositionContainer.SatisfyImportsOnce(fooImporter);
}
catch (CompositionException ce)
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine("Message:").AppendLine(ce.Message);
stringBuilder.AppendLine(new string('*', 42));
foreach (var error in ce.Errors)
{
stringBuilder.AppendLine("Error:").AppendLine(error.Exception.Message);
stringBuilder.AppendLine(new string('*', 42));
}
Assert.Fail(stringBuilder.ToString());
}

Assert.IsNotNull(fooImporter.Foo);
}

[TestMethod]
public void Using_the_class_direct_shows_the_correct_error()
{
var typeCatalog = new TypeCatalog(typeof(Foo));//, typeof(Bar));
var compositionContainer = new CompositionContainer(typeCatalog);

var foo = new Foo();

try
{
compositionContainer.SatisfyImportsOnce(foo);
}
catch (CompositionException ce)
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine("Message:").AppendLine(ce.Message);
stringBuilder.AppendLine(new string('*', 42));
foreach (var error in ce.Errors)
{
stringBuilder.AppendLine("Error:").AppendLine(error.Exception.Message);
stringBuilder.AppendLine(new string('*', 42));
}
Assert.Fail(stringBuilder.ToString());
}

Assert.IsNotNull(foo.Bar);
}

public interface IFoo { }

public interface IBar { }

public abstract class FooBase : IFoo
{
[Import]
public IBar Bar { get; set; }
}

[Export(typeof(IFoo))]
public class Foo : FooBase
{ }

[Export(typeof(IBar))]
public class Bar : IBar { }

public class FooImporter
{
[Import]
public IFoo Foo { get; set; }
}
}
Comments: I ran into the same issue. Very misleading message....

New Post: Release

$
0
0

Hi, two questions:

1 WhenfreedMEF2?

2 MEF2will havebetter integration withMVC4 /WebAPI?

New Post: problem on MEF Winform load plugin DLL

$
0
0

i am new the MEF, i have a winform project and a class DLL project.

i wish not to add the DLL in the winform project, and trying to use MEF to export my class DLL project and import the DLL to winform project.

Could you please guide me step by step how should i need to do?

my class DLL project is

public class UpdateKeyword

how should i export this DLL and import to my WinForm? i am so confusing...

New Post: Removal of System.Composition.Web.Mvc and the support for .NET 4.0

$
0
0

Hola !

 

I would like to start to learn and understand MEF and I am also fixed to Net 4.

Looks like bad politics, the solution file is also VS2012 [??].

Completely disappointed ....

 

Best regards,

 

++mabra

New Post: problem on MEF Winform load plugin DLL

$
0
0

my problem solved during 5am woke up time...

New Post: PartMetadata vs. ExportMetadata

$
0
0

Just in case someone stumbles upon this thread, the above answer is outdated. PartMetadata is used in the implementation of open-generics (and possibly other places I am not aware of).

When using open generics to export a part, two keys are added to the part's metadata dictionary:

  1. "System.ComponentModel.Composition.IsGenericPart" - set to "true" for open generics
  2. "System.ComponentModel.Composition.GenericPartArity" - set to the number of type parameters in the generic part.

These entries are handled internally by MEF, so there's no special need to know this unless you're trying to do some low-level stuff.


New Post: MEF with PostSharp

$
0
0

Hi,

I'm having a problem using PostSharp and MEF together. I have a MEF export that has a reference to an Assembly that is process by PostSharp. When I try to run the application I got an exception trying to load the assembly that is processed by PostSharp. If I disable PostSharp everything works fine. I try to use the FusionLogViewer but the only thing that I see that could help explain the error is that when using PostSharp I get this line on the log: "LOG: This bind starts in default load context." while with PostSharp disabled I get this line "LOG: This bind starts in LoadFrom load context.".

I have the extension assembly and its references in a sub folder of the application.

 

Any help would be appreciated,

Thanks in advance,

Nuno Pereira

New Comment on "Documentation"

$
0
0
Thanks for taking the time to discuss this, I feel strongly about it and love learning more on this topic. If possible, as you gain expertise, would you mind updating your blog with more information? It is extremely helpful for me...thanks http://verchini.com/that-lung

New Comment on "Documentation"

$
0
0
Hello, this is a really fas­ci­nat­ing web blog and I have loved read­ing sev­eral of the arti­cles and posts con­tained upon the site, sus­tain the great work and hope to read a lot more excit­ing arti­cles in the time to come. Thank you so much. <a href="http://vienne.co/tui-xach-thoi-trang" rel="dofollow">tui xach thoi trang</a>

New Post: MEF exports failure in MVC app

$
0
0

Hello, I'm testing with MEF in MVC and I'm experiencing an issue when getting exported parts from my catalog; probably it's just me, but I'm stuck with it. Here is the minimalist scenario:

a) a metadata attribute for exporting controllers from plugins. As such, this attribute will be shared among all the plugins and thus resides in its own independent assembly:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]publicclass ExportControllerAttribute : ExportAttribute, IControllerMetadata
{public ExportControllerAttribute(string name) : base(typeof(IController))
    {
        Name = name;
    }publicstring Name { get; privateset; }
}publicinterface IControllerMetadata
{string Name { get; }
}
b) a sample plugin exporting a controller like:

[ExportController("Alpha")]
[PartCreationPolicy(CreationPolicy.NonShared)]publicsealedclass AlphaController : Controller
...
c) a consumer console app which gets the exported controller like:

AggregateCatalog catalog = new AggregateCatalog(new AssemblyCatalog(Assembly.GetExecutingAssembly()),new DirectoryCatalog(Path.Combine(
        Environment.CurrentDirectory, "Plugins/")));
CompositionContainer container = new CompositionContainer(catalog);var partDef = (from l in container.GetExports<IController, IControllerMetadata>()where l.Metadata.Name == "Alpha"select l).FirstOrDefault();if (partDef != null)
    IController controller = partDef.Value;
This works fine and the exported controller is located and instantiated. (I copied the plugin DLL in its Plugins folder). If instead I try exactly the same code in a MVC web app (Global.asax, copying the same DLLs in a Plugins folder), I can see that the catalog contains my part, but no export are found by the LINQ query above. Could anyone explain?

New Post: MEF exports failure in MVC app

$
0
0

 

  Hi- sounds strange. Have you checked that all code is being built against
the same MVC version, or that the required binding redirects are in place?

Cheers,
Nick

Viewing all 265 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>