Coder Social home page Coder Social logo

mefcontrib / mefcontrib Goto Github PK

View Code? Open in Web Editor NEW
121.0 121.0 45.0 6.07 MB

User contributed extensions for the Managed Extensibility Framework (MEF)

Home Page: http://mefcontrib.codeplex.com

License: Microsoft Public License

C# 99.96% Shell 0.04%

mefcontrib's Introduction

What is MefContrib?

MefContrib is a community-developed set of extensions, tools and samples for the Managed Extensibility Framework (MEF). The project is an open source project, licensed under the MS-PL license. MefContrib is about YOU. With your help we can make it a vibrant resource for MEF developers world-wide.

mefcontrib's People

Contributors

arielbh avatar jimitndiaye avatar kevmoo avatar maartenba avatar mefcontrib avatar petrhosek avatar pwlodek avatar thecodejunkie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mefcontrib's Issues

RegionCreationException with Unity + Mef integration and Prism and Regions

Hello,

I've been trying to figure out how to get MEF and Unity to play nice in a prism context.

Using MEF + Unity can work for some people, but I couldn't figure out how to get it working correctly with prism.

I have a project that runs okay with the integration layer, only when I add a region to the Shell view, a RegionCreationException is thrown, stating that the key couldn't be found in a dictionary.

If a sample project is required for repro purposes, please contact me and I'll provide you one.

the exception is the following : (Note that 'ActionsRegion' is the name of a region in the xaml for the Shell view.)

Microsoft.Practices.Prism.Regions.Behaviors.RegionCreationException was unhandled by user code
Message=An exception occurred while creating a region with name 'ActionsRegion'. The exception was: System.Collections.Generic.KeyNotFoundException: controlType
at Microsoft.Practices.Prism.Regions.RegionAdapterMappings.GetMapping(Type controlType) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\RegionAdapterMappings.cs:line 82
at Microsoft.Practices.Prism.Regions.Behaviors.DelayedRegionCreationBehavior.CreateRegion(DependencyObject targetElement, String regionName) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\Behaviors\DelayedRegionCreationBehavior.cs:line 136.
Source=Microsoft.Practices.Prism
StackTrace:
at Microsoft.Practices.Prism.Regions.Behaviors.DelayedRegionCreationBehavior.CreateRegion(DependencyObject targetElement, String regionName) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\Behaviors\DelayedRegionCreationBehavior.cs:line 143
at Microsoft.Practices.Prism.Regions.Behaviors.DelayedRegionCreationBehavior.TryCreateRegion() in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\Behaviors\DelayedRegionCreationBehavior.cs:line 118
at Microsoft.Practices.Prism.Regions.Behaviors.DelayedRegionCreationBehavior.OnUpdatingRegions(Object sender, EventArgs e) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\Behaviors\DelayedRegionCreationBehavior.cs:line 99
InnerException: System.Collections.Generic.KeyNotFoundException
Message=controlType
Source=Microsoft.Practices.Prism
StackTrace:
at Microsoft.Practices.Prism.Regions.RegionAdapterMappings.GetMapping(Type controlType) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\RegionAdapterMappings.cs:line 82
at Microsoft.Practices.Prism.Regions.Behaviors.DelayedRegionCreationBehavior.CreateRegion(DependencyObject targetElement, String regionName) in c:\release\WorkingDir\PrismLibraryBuild\PrismLibrary\Desktop\Prism\Regions\Behaviors\DelayedRegionCreationBehavior.cs:line 136
InnerException:

MefContrib.Web.Mvc is not correctly handling per-request part creation

Example:

A ShoppingCarController has dependencies on IOrdersRepository and IProductsRepository. Each repository has a dependency on IUnitOfWork. In order to correctly implement the unit of work pattern, both repositories need the same instance of IUnitOfWork.

Currently, the CompositionDependencyResolver creates a filtered catalog based on the NonShared creation policy.

This however causes the filtered container to create a new unit of work for every request during the web request. In my example, each repository will get a different unit of work, which is incorrect.

In order to work correctly, the creation policy must be shared for my IUnitOfWork implementation, but still exist in the filteredCatalog (current code seen below) in order to be disposed of at the end of the web request.

I was able to solve this problem by creating another attribute to denote a per-request creation policy. My filteredCatalog now contains parts that are nonShared or that are annotated with the new attribute.

Is this an appropriate solution?

// Per-request container: only NonShared parts
this.filteredCatalog = new FilteringCatalog(
this.globalCatalog, new HasCreationPolicy(CreationPolicy.NonShared));

MefContrib.Integration.Unity: New Release no longer detects when objects are already instantiated in Unity

We are using CompositeIntegration to be able to instantiate an object with both Unity and MEF. The problem described below occurs now after upgrading to version 1.1. (Our code worked fine with previous versions of MefContrib)

Expected Behavior:

A class instantiates as MEF Export would not instantiated via MEF again, if it is already instantiated via Unity. (worked with prior version)
e.g.,
[Export(typeof(IEventAggregator))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class EventAggregator : IEventAggregator
....
had been instantiated via Unity as a Singleton even though it was also declared as MEF Export as shown above.

Observed Behavior in version 1.1:

Classes now get instantiated via MEF even though they are already instantiated via Unity, e.g., the EventAggregator is no longer a singleton.

Further clues:

A diff of CompositeIntegration shows changes to this class, which seem to cause the issue. Esp. the new Initialize code seems to be modified above and beyond cosmetics. There are a new Strategy and new Lazy policies declared, which indicate a potential place where the code now breaks:
Context.Policies.Set(new LazyResolveBuildPlanPolicy(), typeof(Lazy<>));
Context.Policies.SetDefault( new CompositionContainerPolicy(compositionContainer));

Unfortunately, the sparse documentation of the code makes it very hard for us to debug the code, nor can we revert to the old version because of the memory leak.

Therefore, quick help by the author of the change would be very much appreciated.

Thanks

Jens

DynamicProxyInterceptor with Generator.CreateClassProxy

At the moment the DynamicProxyInterceptor is a little limiting because it requires you to create interfaces for everything you want to intercept.

If it could support Generator.CreateClassProxy, then you would be able to intercept any virtual property/method in a class.

A use case for this is the ability to dynamically add support for INotifyPropertyChanged to a WPF ViewModel (where you would be unlikely to want to write an interface for all of your VMs just to add an interceptor for it). Another use case would be for dynamically adding IDataErrorInfo support to a VM.

A discussion about this is here (with part of a solution - we just need a bit of help to finish this off I think):
http://mef.codeplex.com/discussions/261994
http://mefcontrib.codeplex.com/discussions/261642

Thoughts?

GenericCatalog CreateDynamicExport returing null is some cases

If the importDefinition passed to CreateDynamicExport is a non generic interface the return value could be null. This should never happen or the program will crash.

Using reflector on CatalogExportProvider::GetExportsCore you will see why:

foreach (Tuple<ComposablePartDefinition, ExportDefinition> tuple in valueAllowNull.GetExports(definition))

I see two solutions: set the export before the return value if it is null or change:

if (importDefinitionType.IsClass)
to
if (importDefinitionType.IsClass || importDefinitionType.IsInterface)

I don't know if that change is correct but for now it seems to work around my issue.

Mike

Access to CompositionModelBinderProvider's global Container.

Hello,

For a MVC application I need access to the global container that is used on application level at startup (I don't have a request yet)
.
For this I could replace the existing CompositionDependencyResolver with a custom implementation. But then I'm unable to reuse the CompositionModelBinderProvider because of a hard dependency.

I see a number of ways to solve this. But am uncertain wich you would like most.

  • Can this dependency be abstracted to an interface?

  • Or can the globalContainer of the CompositionModelBinderProvider be made public.

        /// 
    
    
        /// Gets the global container.
        /// 
    
    
        /// The container.
        public CompositionContainer GlobalContainer
        {
            get
            {
                return this.globalContainer;
            }
        }
    
  • Or can the Container property on CompositionModelBinderProvider be replaced with:

        ///  
        /// Gets the container.
        /// 
        /// The container.
        public CompositionContainer Container
        {
            get
            {
                IDictionary items = CurrentRequestContext.Items;
                if (items == null) 
                {
                    return this.globalContainer;
                }
                if (!items.Contains(HttpContextKey))
                {
                    items.Add(HttpContextKey,
                        new CompositionContainer(this.filteredCatalog, true, this.globalContainer));
                }
    
                return (CompositionContainer)items[HttpContextKey];
            }
        }
    

Regards,
Jelle

ExportProvider.GetExportedValue<T>() does not work when using GenericExportHandler

Calling GetExportedValue<T>() on a container making use of GenericExportHandler results in an ArgumentException thrown from TypeHelper.GetImportDefinitionType(ImportDefinition) (more specifically, the call to ReflectionModelServices.IsImportingParameter(definition) on line 14). The exception message is:

ImportDefinition of type 'System.ComponentModel.Composition.Primitives.ContractBasedImportDefinition' cannot be used in this context. Only import definitions produced by the ReflectionModelServices.CreateImportDefinition are supported.
Parameter name: importDefinition

MefContrib.Web.Mvc doubling up [ImportMany] parameters

I recently upgraded my MefContribMVC3 using nuget and now have any parameters marked [ImportMany] on Controller constructors including the imported items twice.

I have a reference to the MEF Container created in the AppStart and if I request the same import using GetExports<> I only get the items once.

I am not sure what is causing the doubling up issue.

No default condition on PartConventionBuilder

I wanted to add a convention for all scanned types (a la StructureMap), but I found that if I didn't use any of the ForType* methods:

        Part()
            .Exports(e =>
            {
                e.Export().Members(t => something);
            });

Then I got an exception (from the assembly scanner). It's pretty easy to do this:

        Part()
            .ForTypesMatching(t => true)
            .Exports(e =>
            {
                e.Export().Members(t => whatever);
            });

but it would be nice not to have to :)

Unfortunately my solution, adding a default predicate in the PartConventionBuilder ctor, broke a lot of tests :(

Unity: Integration API does not support custom export providers

Hi all

Unity integration currently doesn't support custom export providers when going through the "official" RegisterCatalog extension method. This currently forces us to use our own initialization logic (mostly copied from the original sources), which often breaks with new changes (for example today ;)

It would be nice to get an overload that just takes a params IExportProvider[], which would allow us to easily integrate unity, and still configure MEF with both catalogs and export providers.

Cheers, and thanks for a set of awesome components!
Philipp

Edit:

Here's my current integration code that uses a custom export provider:

    public UnityServiceContainer(IUnityContainer container, ComposablePartCatalog catalog)
    {
        Guard.ArgumentIsNotNull(container, () => container);

        this.Container = container;
        container.AddNewExtension<LazySupportExtension>();

        if (catalog != null)
        {
            //init custom provider for ExportFactory<T> support
            var efProvider = new ExportFactoryProvider();

            //make unity types available to MEF
            var adapter = new UnityContainerAdapter(container);
            var unityExportProvider = new ContainerExportProvider(adapter);

            var extension = new CompositionIntegration(true, efProvider, unityExportProvider);
            container.AddExtension(extension);

            //re-assign the MEF container to our export provider
            efProvider.SourceProvider = extension.CompositionContainer;

            //register MEF catalog with Unity
            extension.Catalogs.Add(catalog);

            //register the MEF container in Unity
            container.RegisterInstance(extension.CompositionContainer, LifetimeManagers.CreateContainerControlled());
        }
...

}

MefContrib.MVC doesn't handle parts with ContractName (ConventionCatalog or PartRegistry bug?)

For simple repo, go file new project, ASP.NET MVC 3 app, then add the NuGet package MefContrib.MVC3

Create a simple property import or constructor import with a custom contract name.

[Import("MyString")]
public string MyString { get; set; }

public HomeController([Import("MyOtherString")] string myOtherString)
{
}

Set a breakpoint just after the catalog has been created in the WebActivator start method.

var catalog = new AggregateCatalog(
    new DirectoryCatalog("bin"),
    new ConventionCatalog(new MvcApplicationRegistry()));

// breakpoint here

Inspect catalog.Parts, locate the controller part definition and look under import definitions. What you'll find is that the ExportTypeIdentity is being used as ContractName.

I'm not sure whether this is a bug in the ConventionCatalog or PartRegistry but it's definitely some kind of bug.

ConventionPartCreator incorrectly gets import parameter definition for generic parameters

ConventionPartCreator.GetImportParameterDefinition(importConvention, parameter) currently uses parameter.ParameterType.GetActualType() to determine the parameter's importDefinition. This does not work for generic parameters.

Ex: if Foo's ctor requires an IRepository, GetImportParameterDefinition will determine that the contract name is Bar instead of IRepository(Bar).

All ConventionPartCreatorTests and ConventionsCatalogTests passed with the following change to GetImportParameterDefinition

//var actualType = parameter.ParameterType.GetActualType();
var actualType = parameter.ParameterType;

Am I missing something?

null dependencies cause NullReferenceException in unity integration.

We have some dependencies that are set to null in our unit tests:

container.RegisterType<IInterface>(new InjectionFactory(c => null));

and this causes a NullReferenceException in the PostBuildUp method in ComposeStrategy.cs

It looks like the offending line is:

var type = context.Existing.GetType();

In this case context.Existing is null, so we should just check for this and return in that case.

Custom Generic Collections not Exported by GenericExportHandler

The GenericExportHandler class will only export the generic type parameters for IEnumerable(Of T) types and not the IEnumerable(Of T) type itself. The GetExports method of the GenericExportHandler class contains the code below which essentially switches the import definition to that of the generic type parameter, ignoring the original IEnumerable(Of T) import definition.

    if (TypeHelper.IsGenericCollection(importDefinitionType))
    {
        importDefinitionType = TypeHelper.GetGenericCollectionParameter(importDefinitionType);
    }

This means if I modify the MefContrib.Samples.Generics sample so that the Repository(Of T) class and IRepository(Of T) interface implement IEnumerable(Of T) [as shown below], then GenericExportHandler will never export Repository(Of T) for IRepository(Of T).

    public interface IRepository(T) : IEnumerable(T)
    {
        T Get(int id);
        void Save(T instance);
    }

    [Export(typeof(IRepository<>))]
    public class Repository<T> : IRepository<T> where T : new()
    {
        public T Get(int id)
        {
            return new T();
        }

        public void Save(T instance)
        {
            Console.WriteLine("Saving {0} instance.", instance.GetType().Name);
        }

        public IEnumerator<T> GetEnumerator()
        {
            throw new NotImplementedException();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }

CompositionDependencyResolver's globalContainer does not use GenericCatalog

Ex. construct a CompositionDependencyResolver using an aggregateCatalog that contains a GenericCatalog

Prior to the fix for issue #18, the globalCatalog was set to the CompositionDependencyResolver 's catalog argument and then used to construct the globalContainer. The globalContainer is then used as the ExportProvider for the container used as the service provider.

Since switching to a FilteredCatalog, it looks like none of the providers in the new container's AggregatingExportProvider know about the GenericCatalog. This results in generic parts not being found.

One solution is to create a CatalogExportProvider from the GenericCatalog (if it exists) and add it as an ExportProvider to the new container (in addition to the globalContainer).

//this.globalCatalog = catalog

this.completeCatalog = catalog;
this.globalCatalog = new FilteringCatalog(
     this.completeCatalog, new HasPartCreationScope(PartCreationScope.Global));

this.globalContainer = new CompositionContainer(this.globalCatalog, true, null);

Better Error Messages

I am not sure if we are the only ones that run into this, but we have multiple projects in our solution and when large change are made we almost always get the following type of error, which is a pain to track down without digging up more information.

Server Error in '/WebUI' Application.

Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.]
System.Reflection.RuntimeModule.GetTypes(RuntimeModule module) +0
System.Reflection.Assembly.GetTypes() +159
System.ComponentModel.Composition.Hosting.AssemblyCatalog.get_InnerCatalog() +126
System.ComponentModel.Composition.Hosting.AssemblyCatalog.get_Parts() +9
lambda_method(Closure , ComposablePartCatalog ) +20
System.Linq.d__142.MoveNext() +267 System.Linq.<SelectManyIterator>d__142.MoveNext() +507
System.Collections.Generic.List1..ctor(IEnumerable1 collection) +472
MefContrib.Hosting.Interception.InterceptingCatalog.GetParts() +132
System.ComponentModel.Composition.Primitives.ComposablePartCatalog.GetExports(ImportDefinition definition) +139
MefContrib.Hosting.Interception.InterceptingCatalog.GetExports(ImportDefinition definition) +51
System.ComponentModel.Composition.Hosting.CatalogExportProvider.GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition) +188
System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition) +78
System.ComponentModel.Composition.Hosting.AggregateExportProvider.GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition) +212
System.ComponentModel.Composition.Hosting.ExportProvider.TryGetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition, IEnumerable`1& exports) +47
System.ComponentModel.Composition.Hosting.CompositionContainer.GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition) +100
System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition) +78
System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(Type type, Type metadataViewType, String contractName) +52
MefContrib.Web.Mvc.CompositionDependencyResolver.GetService(Type serviceType) +33

Unity integration does not dispose MEF Components.

I think the problem is in ComposiotionIntegration.

It looks like the MEF components are owned by the CatalogExportProvider created in PrepareCompositionContainer.

My testing shows that this is never disposed when the MEF container is, and hence none of the components retrieved from MEF are disposed.

I think the fix is to dispose the provider explicitly in CompositionIntegration.Dispose.

PartCreationScope does not work.

I think the scope is case sensitive.
When I add

[ExportMetadata("scope", "Global")]
it works, if however I make it "Scope" it fails.

When I inspect the container after adding

[PartCreationScope(PartCreationScope.Global)]
it shows a scope with a upper-case letter.
MefContrib.Web.Mvc/Filter/HasPartCreationScope.cs line 52 thus should be

 var key = "Scope"

Regards,
Jelle

[ImportingContsructor] doesn't work with an open generic.

To fix add the following to TypeHelper

public static bool IsReflectionParameterImportDefinition(ImportDefinition definition)
{
return definition.GetType().Name.Equals("ReflectionParameterImportDefinition");
}

and change the following in GenericCatalog.GetExports(ImportDefinition definition): if (!exports.Any() && TypeHelper.IsReflectionMemberImportDefinition(definition))

to: if (!exports.Any() && (TypeHelper.IsReflectionMemberImportDefinition(definition) || TypeHelper.IsReflectionParameterImportDefinition(definition)))

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.