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

New Post: Resolving Open Generics with RegistrationBuilder

$
0
0

My open generic works fine when exported with an attribute, such as

 

 

[Export(typeof(IRepository

<>))] 

 

publicclassExampleRepository<T> : IRepository<T>whereT : class

 

 However, I haven't been able to work out how to export this with RegistrationBuilder. Neither of these work

 

builder.ForTypesDerivedFrom(typeof(IRepository<>)).ExportInterfaces();

builder.ForTypesDerivedFrom(typeof(IRepository<>)).Export(eb => eb.AsContractType(typeof(IRepository

 <>)));

Has anyone worked out how to export open generics from RegistrationBuilder?

Is it impossible?

 

 

 

 

 


New Post: Resolving Open Generics with RegistrationBuilder

$
0
0

Hi Kathleen,

Here is a response from Kevin on the MEF team.

Yes it is possible to export generics using RegistrationBuilder.

There is a bug in Desktop MEF that we didn’t fix. We did fix it in Oob MEF.

The work around is to use code like this, the bold is what she needs to add the rest is to make it a complete sample:

using System;

using System.Collections.Generic;

using System.ComponentModel.Composition;

using System.ComponentModel.Composition.Hosting;

using System.ComponentModel.Composition.Registration;

using System.Linq;

using System.Reflection;

using System.Text;

using System.Threading.Tasks;

namespace ConsoleApplication26

{

publicinterfaceIRepository<T>

{

IEnumerable<T> GetItems();

}

publicclassExampleRepository<T> :IRepository<T>where T :class

{

publicIEnumerable<T> GetItems()

{

returnnewList<T>();

}

}

[Export]

publicclassImporter

{

[ImportMany]

publicIEnumerable<string> Items;

}

classProgram

{

privatestaticbool IsGenericDescendentOf(TypeInfo openType, TypeInfo baseType)

{

if (openType.BaseType == null)

{

returnfalse;

}

if (openType.BaseType == baseType.AsType())

{

returntrue;

}

foreach (Type typein openType.ImplementedInterfaces)

{

if (type.IsConstructedGenericType && (type.GetGenericTypeDefinition() == baseType.AsType()))

{

returntrue;

}

}

return IsGenericDescendentOf(IntrospectionExtensions.GetTypeInfo(openType.BaseType), baseType);

}

privatestaticbool IsDescendentOf(Type type, Type baseType)

{

if (((type == baseType) || (type == typeof(object))) || (type == null))

{

returnfalse;

}

TypeInfo typeInfo = IntrospectionExtensions.GetTypeInfo(type);

TypeInfo info2 = IntrospectionExtensions.GetTypeInfo(baseType);

if (typeInfo.IsGenericTypeDefinition)

{

return IsGenericDescendentOf(typeInfo, info2);

}

return info2.IsAssignableFrom(typeInfo);

}

staticvoid Main(string[] args)

{

var reg = newRegistrationBuilder();

reg.ForTypesMatching((t) =>

{

return IsDescendentOf(t, typeof(IRepository<>));

}).Export((eb) => eb.AsContractType(typeof(IRepository<>)));

var cat = newTypeCatalog(newType[] {typeof(ExampleRepository<>),typeof(Importer) }, reg );

var container = newCompositionContainer(cat);

var importer = container.GetExportedValue<Importer>();

if (importer.Items == null)

{

Console.WriteLine("Failed");

}

}

}

}

hth

cheers

-alok

From: KathleenDollard [email removed]
Sent: Sunday, January 20, 2013 2:53 PM
To: Alok Shriram
Subject: Resolving Open Generics with RegistrationBuilder [MEF:430218]

From: KathleenDollard

My open generic works fine when exported with an attribute, such as

[Export(typeof(IRepository

However, I haven't been able to work out how to export this with RegistrationBuilder. Neither of these work

builder.ForTypesDerivedFrom(typeof(IRepository

<>)).ExportInterfaces();

builder.ForTypesDerivedFrom(typeof(IRepository<>)).Export(eb => eb.AsContractType(typeof(IRepository

<>)));



Has anyone worked out how to export open generics from RegistrationBuilder?

Is it impossible?

<>))]

publicclassExampleRepository<T> :IRepository<T> whereT :class

New Post: MEF with PostSharp

$
0
0

Hi,

I’ve received a response from SharpCrafters support forum that give me a better understanding of what was happening.

As far as I understand MEF loads the assemblies into the LoadFrom binding context and PostSharp looks for the assemblies in the default Load binding context.

I was able to make the error disappear by handling the AppDomain.AssemblyResolve event and look for the assembly in AppDomain.CurrentDomain.GetAssemblies() because the assembly is already loaded, but in a different context.

My question now is why are assemblies loaded by MEF loaded into the LoadFrom context? What side effects can this solution have? Will I have problems if two different MEF extensions have dependencies to different versions of the same assembly by using the default Load context?

Thanks for the help,

Nuno Pereira

New Post: How to reset mef container to implement Logout for my silverlight app

$
0
0

I'm having the same problem and need to "reset" the MEF container and clear out the shared parts.
This is a dealbreaker for using MEF for IoC if I cannot empty out the container. 

As Dimpu575 stated, ReleaseExports only works on non-shared instances.

Jaans 

PS: @Dimpu575 - Did you find a way to solve this issue yet? 

New Post: How to reset mef container to implement Logout for my silverlight app

$
0
0

Have you considered simply creating a whole new container and disposing the old one?

cheers,

Nick

New Post: How to reset mef container to implement Logout for my silverlight app

$
0
0

Thanks - yes I did but I wasn't able to successfully do so because I'm getting the exception below when recreating the new one.

"The container has already been initialized either by another call to InitializeContainer or by someone causing the default container to be constructed. Ensure that InitializeContainer is one of the first things that happens in the application host to ensure that it is ready for the first composition."

PS: This happens upon this call (2nd execution of it)

_container = CompositionHost.Initialize( catalog );

New Post: How to reset mef container to implement Logout for my silverlight app

$
0
0

@Jaans,

I ended up converting all my viewmodels as non shared and use some static methods and properties to share info btwn viewmodels. I dont know if that is right way but i had to move on :( 

Created Issue: Shared part instantiated twice [14604]

$
0
0
When a:
* Shared part
* Involved in a circular dependency
* Has more than one export

Then the part should be created only once but is instantiated twice.

Found in version 1.0.16.

Failing test case below.

```
[Shared, Export, Export("named")]
public class TwoExports
{
[Import]
public CircularImporter Importer { get; set; }
}

[Shared, Export]
public class CircularImporter
{
[Import]
public TwoExports TwoExports { get; set; }
}

[TestMethod]
public void SharedPartWithManyExportsInCircularityCreatedOnce()
{
var container = new ContainerConfiguration()
.WithPart<TwoExports>()
.WithPart<CircularImporter>()
.CreateContainer();

var a = container.GetExport<TwoExports>("named");
var b = container.GetExport<TwoExports>();
Assert.AreSame(a, b);
}
```


New Post: Assembly version as ExportMetadata

$
0
0
How can you use the current build version of an assembly as exportmetadata?

Commented Issue: Shared part instantiated twice [14604]

$
0
0
When a:
* Shared part
* Involved in a circular dependency
* Has more than one export

Then the part should be created only once but is instantiated twice.

Found in version 1.0.16.

Failing test case below.

```
[Shared, Export, Export("named")]
public class TwoExports
{
[Import]
public CircularImporter Importer { get; set; }
}

[Shared, Export]
public class CircularImporter
{
[Import]
public TwoExports TwoExports { get; set; }
}

[TestMethod]
public void SharedPartWithManyExportsInCircularityCreatedOnce()
{
var container = new ContainerConfiguration()
.WithPart<TwoExports>()
.WithPart<CircularImporter>()
.CreateContainer();

var a = container.GetExport<TwoExports>("named");
var b = container.GetExport<TwoExports>();
Assert.AreSame(a, b);
}
```

Comments: Issues is in DiscoveredPart.cs -> DiscoveredPart.GetActivator(). This code is reentrant during activator creation, but doesn't account for that fact. Because of this, it creates two activators for the one part; the activators themselves carry the shared instance, so two activators == two shared instances. The fix is simple - the class just needs to detect when it is already initialising, and return a thunk in that case. The class is single-threaded so no synchronisation is required. First the class needs a Boolean to track whether initialisation of the activator has started: ``` bool _activatorCreationStarted; ``` Then after the initial check in GetActivator(): ``` public CompositeActivator GetActivator(DependencyAccessor definitionAccessor, IEnumerable<CompositionDependency> dependencies) { if (_partActivator != null) return _partActivator; ``` We insert a new condition: ``` if (_activatorCreationStarted) return (c, o) => _partActivator(c, o); _activatorCreationStarted = true; ``` The tests now pass, including the new one in the issue above.

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

$
0
0
I have export attributes on my views. and each view imports a viewmodel(stocktrader design)

based on some requiremenet I had to do call satisfyimports. but when I call this, I get above error.(mentioned in subject line)
I went into the CompositionInitliaser class and commented below check and everything seems to work fine.
public static void SatisfyImports(ComposablePart part)
        {
            if (part == null)
            {
                throw new ArgumentNullException("part");
            }

            var batch = new CompositionBatch();

            batch.AddPart(part);

            //if (part.ExportDefinitions.Any())
            //{
            //    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
            //            @"Cannot call SatisfyImports on a object of type '{0}' because it is marked with one or more ExportAttributes.", part.ToString()), "part");
            //}
i think i'm missng something. can anyone help me understand the consequences of commenting above check?

New Post: MEF loading multiple instances of my MVVM Modules

$
0
0
I'm new to MEF, and MVVM, and I'm having some problems.

I've finally got my View and ViewModel binding in my app; I'll explain what I've got and then the problem, hoping someone could help figure out what my problem is.

I have a host app - MVVM, the main view loads plugins from a dir and displays their name across the top. It also loads some items and displays them down the side.
public class Item
{
public Item()
{
}
public int Number { get; set; }
public string Name { get; set; }
}
To correctly load my modules, I was required to expose a public property of ResourceDictionary in the code behind of the view. I also expose the class of the viewmodel.

In my main app constructor I get all the resource dictionary types and add them to the app.current.resourcedictionary

then I get all my plugins and do a
foreach( var plugin in _plugins)
{
Plugins.Add(p.value);
}
_plugins is an IEnumerable<Lazy<PlugingViewBase, IPluginMetaData>>;

In the constructor of each plugin I generate a GUID and console.writeline the new GUID.

when I call the .value of I get an init in the output, when the resourcedictionary is called I get an init as well...

What I want, is when changing the Item on the left, to update a textblock in the view of the plugin, this does not happen. However I have a button on the plugin view which does correctly update the TextBlock.

I think although all my classes have a creationpolicy shared - it still seems to create more than one instance.

Thanks for reading all that, All this MEF / MVVM is heavy going, so I'd be very glad of any assistance!

New Post: MEF loading multiple instances of my MVVM Modules

$
0
0
Hi- which MEF version are you using, where are you creating the container, and how do you request the exports/satisfy the imports of the parts involved?

cheers,
Nick

New Post: Assembly version as ExportMetadata

$
0
0
For all exports, or just a selection?

The former, I'm not sure about. There are a couple of days to achieve the
latter.

If you're using conventions, you can do this in an Export(x => ...)
statement using AddMetadata().

If you're using attributes only, a custom MetadataAttribute can do this.

Let us know which approach you're using and with what version of MEF.

Cheers,
Nick

New Post: MEF loading multiple instances of my MVVM Modules

$
0
0
Hi Nick,

I'm using the version that comes with .Net 4.5, but I solved my problem this morning!

The problem was that in my View the Xaml I was assigning the DataContext - so when my view model was loaded, it loaded the View which then loaded another instance of the ViewModel to attach to the view! consequentially I ended up with two ViewModels which was causing my problems with the INotifyPropertyChanged events.

The solution was to remove the DataContext from the xaml and in the code behind have
[import]
public myViewModel context
{
set
{
this.DataContext = value;
}
}
and that worked!!

New Post: Resource keyname conflict between application resources

$
0
0
We have several independent apps that we are trying to tie together as a MEF application. Each of the original apps had common resources declared in App.Xaml. Now with MEF, there are no instances of those apps and consequently, no common resources. That causes the xaml that depended on those StaticResources to fail.

So I added my App's resources through code like this (in Delphi Prism):
   class procedure GlobalResources.LoadResources;

      procedure LoadResource( resourceUri : String );
         var 
            rd : ResourceDictionary;
         begin
         rd := new ResourceDictionary( Source := new Uri( resourceUri, UriKind.Relative ) );
         Application.Current.Resources.MergedDictionaries.Add( rd );
         end;

      begin
      LoadResource( '/GuardianEditObservation;component/Assets/ConverterResources.xaml' );
      LoadResource( '/GuardianEditObservation;component/Assets/Styles.xaml' );
      LoadResource( '/GuardianEditObservation;component/Assets/EditObservationViewResources.xaml' );
      end;
That made everything work in the MEF application. However, these resources all have to have keys. And some other app might be using the SAME keys.

Isn't this going to be a problem if two app (xaps) contain global resources with the same keys? Is there a way to specify the StaticResource so that it resolves the ambiguities?

New Post: Basic cross process singleton

$
0
0
I am trying to use MEF with VS2008 .NET 3.5 (Mef_Preview_9) to create a cross process singleton and everything I have tried returns a new instance.

I have created MetaDataModelServer and Client projects, both of which reference a separate IMetaDataModelServer project. When the Client is run multiple times I want them to return the same MetaDataModelServer instance but they always create a new one. My reading says that the default is [PartCreationPolicy(CreationPolicy.Shared)] but even explicitly specifying it, I still get a new instance.

I am feeling a bit stupid about this so please feel free to point out the obvious.
// IMetaDataModel.dll 
   [InheritedExport(typeof(IMetaDataModelServer))]
    public interface IMetaDataModelServer
    {
        DateTime DateTimeCreated { get ;  }
    }

    [InheritedExport(typeof(IMetaDataModel))]
    public interface IMetaDataModel
    {
        DateTime DateTimeCreated { get; }
    }

// MetaDataModel.dll references IMetaDataModel.dll 
    public class MetaDataModelServer : IMetaDataModel.IMetaDataModelServer {}
    public class MetaDataModel : IMetaDataModel.IMetaDataModel {}

// Client.dll references IMetaDataModel.dll
    class Client
    {        
        [Import(typeof(IMetaDataModel.IMetaDataModelServer))]
        public IMetaDataModel.IMetaDataModelServer MetaDataModelServer;

        public Client()
        {
            Compose();
            MessageBox.Show("ClientAddinConsole.MetaDataModelServer " + " " + MetaDataModelServer.DateTimeCreated.ToString() );
        }

        private void Compose()
        {
            dirCatalog = new DirectoryCatalog(@"D:\Projects\MEFExample\MetaDataModel\bin\Debug");
            CompositionContainer container = new CompositionContainer(dirCatalog);
            container.SatisfyImportsOnce(this);
            //container.ComposeParts(this);
     }  
   }

New Post: Basic cross process singleton

$
0
0
Hi there- MEF's "sharing" applies within a single instance of the composition container. There's no support for inter-process sharing, which I believe needs a different/morr resilient implementation approach than MEF aims to provide.

cheers,
Nick

New Post: Reloading an updated version of XAP through DeploymentCatalog does not recompose correctly

$
0
0
Did you ever solve this issue? I am going down a similar path with switching to MEF instead of Prism to download modules. Thanks...

New Post: MEF, Silverlight, and Browser cached files/updating xaps

$
0
0
I read that the DeploymentCatalog does not support Silverlight cached assemblies. (Otherwise known as TPEs). This means that DeploymentCatalog will not download referenced assemblies that are packaged with the Silverlight caching infrastructure (.extmap).

I am assuming that this restriction does not apply to browser cached files. Is this correct?

If the xap on the server is updated, will the DeploymentCatalog/Browser be able to automatically detect this and download the latest version from the server? If not, how can this be addressed.

Thanks...
Viewing all 265 articles
Browse latest View live


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