Package Catalog

Sep 14, 2009 at 5:01 PM

I have a SL3 app that was previously compiled in Preview 6. I just recompiled with the Aug 27 SL drop (which appears parallel to rather than part of the Preview 7 drop the same day).

I know get an error that package catalog is not availble. If this has been removed, how do you discover catalogs in Silverlight?

I must be missing something obvious.

Thanks, Kathleen

Sep 14, 2009 at 5:31 PM

Hi Kathleen,

For the default XAP, the package is automatically loaded, and you kick-start the composition process by calling PartInititializer.SatisfyImports().

Loading secondary XAPs is still on our radar - you can get PackageCatalog in source form from the PictureViewer sample. It's no longer in the MEF project because we're aiming to ship it elsewhere.

Hope this helps,

Nick

Sep 14, 2009 at 8:34 PM

OK,

Can you access the container and use a GetExports in SL Preview 7?

It seems that SL and .NET 4.0 have a split in basic approach in this rev. Is that accurate?

I like the SL3 approach, its just going to be somewhat painful for their to be different models in the two "in the box" versions.

It will be nice when PackageCatalog gets split out. I found splitting it out from picture viewer to be non-trivial - partly because I was also converting it. Hopefully we'll get aspect to it in a "toolkit" type approach.

Kathleen

Sep 14, 2009 at 8:55 PM

If you initialize the container yourself, you can access it - the common/*highly* recommended pattern though is to use PartCreator<T>.CreatePart() instead of GetExports(). Any reason this doesn't fit your needs?

The .NET 4 approach still works on Silverlight, but we encourage a simpler model as the default.

Agreed on PackageCatalog. We're working towards that now.

Nick

Sep 14, 2009 at 8:55 PM

Now that I'm resolving imports using SatisfyImports (which is very, very sweet by the way) do I need to do anything to dispose the container before I close the app?

Sep 14, 2009 at 9:29 PM

In the particular case I just encountered I worked around it as it was startup test code (to ensure validity of the container on startup).

The problem is precisely that it is Silverlight. The same code exists on the client and server side compiled against different libraries. Just like before we had a SL MEF, I can split the code to do anything that requires dynamic creation into server/SL specific partial classes. But that's a pain.

For example: A user needs to create a new role. The role is known as an IRoleUser. To create a new one users different code on the client and server side, even though the vast majority of the code in the User class is in a file linked across the two platforms.

I realize this is pain because this is the bleeding edge, running with scissors, all that. But I think this split personaltiy is going to be painful for this year. I also think the SL3 approach is sufficiently superior that getting the PartCreator approach out via a Toolkit would be helpful. As long as the API is the same, I think we can take a slight perf hit on the main .NET platform if necessary to have an avenue to identical behavior.

I just don't want to see the entropy of a bazillion people working out their own part initializer or package catalog. These are both fairly requird pieces, that we just aren't likely to have
"in the box" So, trying to push to a stable API is the next best thing. I'm optimistic that SL3 IS the stable API.

If there isn't a goal for matching API's across the .NET platform and Silverlight I'd like to scream.

 

Sep 14, 2009 at 10:02 PM

Nick,

Here's a real example of a pain point. This is real code from a DTO class which is shared across the .NET and Silverlight boundary where almost everything else in the system works across both platorm. This split API is a disaster for me. OK, so this is generated code or I could finesse by giving up MEF on collections. But what about authorization and validation where it is critical to share code?

On the .NET side I am happy with this...

    <Import()> _
    Private _roleUsers As IRoleUserCollection
    Public ReadOnly Property RoleUsers() As IRoleUserCollection Implements IUser.RoleUsers
        Get
            Return _roleUsers
        End Get
    End Property

But that code won't work in Silverlight because the import is on a private field. So, in Silverlight I need something like

    Private _roleUsers As IRoleUserCollection
    Public ReadOnly Property RoleUsers() As IRoleUserCollection Implements IUser.RoleUsers
        Get
            If _ruleUsers Is Nothing
                 _roleUsers = PartCreator(Of IRoleUserCollection).CreatePart()
            End If
            Return _roleUsers
        End Get
    End Property

Everytime I retrieve something in a linked class running on both platforms I have to create separate partial classes for each platform just to manage MEF? I don't think so. 

We have to have a unified API across the SL and .NET boundary. It does not have to be in the box, but it does have to be a blessed API that isn't going to change out from underneath us.

Actually, you might guess this is the calm version of what I'm saying. Perhaps this should go off line. I'll also ping Glenn as well.

Kathleen

 

 

 

 

Sep 14, 2009 at 10:21 PM

Hi Kathleen

Long term the goal is there to match up the APIs. Any work we do in SL4 will be pouring into future versions of the framework, though there may be slight differences based on the platform. As an example we don’t have DirectoryCatalog in Silverlight, because it doesn’t make sense. In Silverlight you access assemblies and such through XAPs. Another example would be PartInitializer. In Silverlight, when PartInitializer is called the first time, a container is created with a catalog that contains all the assemblies from the current XAP. On the desktop however, there is no current XAP, so it is likely that the implementation will differ perhaps using an Extensions folder underneath the bin. In general though the functionality will remain the same for the caller.

Regards

Glenn

From: kathleendollard [mailto:notifications@codeplex.com]
Sent: Monday, September 14, 2009 2:30 PM
To: Glenn Block
Subject: Re: Package Catalog [MEF:68886]

From: kathleendollard

In the particular case I just encountered I worked around it as it was startup test code (to ensure validity of the container on startup).

The problem is precisely that it is Silverlight. The same code exists on the client and server side compiled against different libraries. Just like before we had a SL MEF, I can split the code to do anything that requires dynamic creation into server/SL specific partial classes. But that's a pain.

For example: A user needs to create a new role. The role is known as an IRoleUser. To create a new one users different code on the client and server side, even though the vast majority of the code in the User class is in a file linked across the two platforms.

I realize this is pain because this is the bleeding edge, running with scissors, all that. But I think this split personaltiy is going to be painful for this year. I also think the SL3 approach is sufficiently superior that getting the PartCreator approach out via a Toolkit would be helpful. As long as the API is the same, I think we can take a slight perf hit on the main .NET platform if necessary to have an avenue to identical behavior.

I just don't want to see the entropy of a bazillion people working out their own part initializer or package catalog. These are both fairly requird pieces, that we just aren't likely to have
"in the box" So, trying to push to a stable API is the next best thing. I'm optimistic that SL3 IS the stable API.

If there isn't a goal for matching API's across the .NET platform and Silverlight I'd like to scream.

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Sep 14, 2009 at 10:30 PM

No, when the app domain shuts down everything will be released.

Glenn

From: kathleendollard [mailto:notifications@codeplex.com]
Sent: Monday, September 14, 2009 1:56 PM
To: Glenn Block
Subject: Re: Package Catalog [MEF:68886]

From: kathleendollard

Now that I'm resolving imports using SatisfyImports (which is very, very sweet by the way) do I need to do anything to dispose the container before I close the app?

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Sep 15, 2009 at 12:30 PM

I wanted to follow up to say that as I thought about it last night, this is probably a bad idea:

  Private _roleUsers As IRoleUserCollection
    Public ReadOnly Property RoleUsers() As IRoleUserCollection Implements IUser.RoleUsers
        Get
            If _ruleUsers Is Nothing
                 _roleUsers = PartCreator(Of IRoleUserCollection).CreatePart()
            End If
            Return _roleUsers
        End Get
    End Property

It accesses the container for a simple import fulfillment. It is probably a better idea to make a public importing constructor.

But this does highlight a challenge that SL presents to MEF, and that's passed on to us as we design with MEF on SL. Because SL locks down reflection to private members, the design needs to relax scope. In general, making changes to the surface of objects due to an internal decision breaks black box design and specifically expanding scope because of an internal technique is unfortunate. But SL has special rules to keep it safe, which is essential.

Thus, you either make your public properties read/write, or you make a backing field public (the worst approach, imo), or you offer a public constructor when you wish the part only to be constructed via MEF - all of which allow MEF to work as it was intended.

Or, you use a hack to preserve the object surface but directly or indirectly access the container. It's better to access the container indirectly, and if the code sits only in SL, you can use code like this here (which is air code so may not be quite right). If the code is linked between SL and .NET it has to hit the lowest denominator, which is currently .NET. Therefore, you have to expose the container and hit it via GetExports.

It was not obvious to me how to build the container, so I'll add this in case its also not obvious to someone else. SL has a Deployment class which exposes the assemblies of the current package via AssemblyParts. Not that SL assembly parts have nothing to do with MEF parts, just a vague word used a different way. WIth a surface area the size of .NET its actually surprising this doesn't happen more often.

So, I wound up working through this problem here publically, so I thought I should include a summary of where I wound up with this.

Thanks again to Glenn and Nick for thier help.
Kathleen

Coordinator
Sep 15, 2009 at 4:39 PM

You should be able to mark your backing fields as internal (instead of private), and put an InternalsVisibleTo attribute on your assembly to allow MEF to access its internal fields.

Daniel

Sep 17, 2009 at 3:45 AM

Daniel,

Thank you . This is a good solution to the problem I was having.

Is there a security downside to this? It seems that if you are controlling what's in the package, you won't pick up any bad code. It does mean that you've expanded the scope of your variable, and increased the surface area of the class within the assembly (although you can mitigate this with EditorBrowsable).

Kathleen