Subdirectories filled with resource dlls

Mar 22, 2010 at 7:16 PM
Edited Mar 22, 2010 at 7:25 PM

Hi all,

I'm facing the following situation:

I have a framework for Web namespace, and it uses MEF to compose somethings. When I run my website, that uses my framework dll, through the VS 2008 web server my compose routine works fine. Otherwise when I'm running the application through IIS the same compose routine does not work well the ImportMany collections are empty. It is important to say, that the compose routine does not throw any kind of exception, it just does not load my ImporMany collection.

I've excluded those subdirectories (en, en-US, etc...) that contain the resources dlls from my web framework and for my surprise the application's started well and was working fine. So I've tried to put those directories back and the error's returned.

I've already tried, for test, to give FullControl to Enyone on the Application Bin directory (subdirectories to), but it did not worked fine.

During my troubleshoting process I've noticed that on the property Parts of my DirectoryCatalog, those resource.dlls do not appear on the list, but my web framework dll was there.

Has anyone any Idea of what is going on with my application? Is this a limitatio of MEF?

Developer
Mar 22, 2010 at 10:56 PM

The resource assemblies shouldn't have any effect on the composition unless some of them have Exported types in them which they shouldn't unless you have explicitly added something in there.

A few questions: 
1) How many things do you expect your imported collection to contain?
2) Do the items you expect to be there have dependencies themselves (i.e. do they have imports)?

Right now I don't have enough information to figure out why this would fail, my best guess would be that some dependency is being duplicated (i.e the same dll in multiple directories) and it is causing the item you are trying to import to be rejected. 

Mar 23, 2010 at 12:54 PM
Edited Mar 23, 2010 at 6:41 PM

In fact the resources DLLs have the same name, exactly the same, but their content is different. 

Responding to your questions:

1) I have a class that have two properties that are composed by MEF. These properties have not a max number of items, but one must have at least 7 and other 5.

2) The items that will be part of the collectoin don't have Imports.

Yesterday I set the IIS user of my application, to the local machine administrator. It worked fine, wich means the problem is some kind of execution permission, because I've already gave FullControl permission to Enyone on the Application Bin folder. 

What are the permissions that the IIs user need to have in order to execute the compose without problems?

I hope thi new information could help you to find out if this is a problem or if I'm missing something.

Developer
Mar 23, 2010 at 6:36 PM

OK this does sound like it is a permissions issue. How are you constructing your catalog? Are you creating multiple DirectoryCatalogs? Also are you getting any errors constructing any of those catalogs for the directories in question?

Mar 23, 2010 at 6:44 PM

I'm not getting any error, and I'm two compose on that DLL, one is using an AssemblyCatalog and other is using an AggregateCatalog with an DirectoryCatalog and an AssemblyCatalog.

In both cases the compose routine works fine running from IIS if the Physical Path Credential are set to a machine administrator. Otherwise the compose does not work well.

Developer
Mar 23, 2010 at 6:48 PM

Can you share the code you are using to setup your catalogs? Also can you list out what your directory structure looks like?

Mar 23, 2010 at 7:23 PM

Of course I can.

The directory structure is like this:

Bin

-en

-en-US

-es

and inside this subdiretories I have dlls like MyName.resource.dll. Outside those subdir, in the mai dir Bin i have MyName.dll.

The code I'm using is like this:

 

AssemblyCatalog assCatalog = new AssemblyCatalog(this.GetType().Assembly.CodeBase);
                CompositionContainer container = new CompositionContainer(assCatalog);
                CompositionBatch batch = new CompositionBatch();
                batch.AddPart(this);
                container.Compose(batch);

1)

AssemblyCatalog assCatalog = new AssemblyCatalog(this.GetType().Assembly.CodeBase);

CompositionContainer container = new CompositionContainer(assCatalog);

CompositionBatch batch = new CompositionBatch();

batch.AddPart(this);

container.Compose(batch);

2)

DirectoryCatalog dircatalog = new DirectoryCatalog(path);

AssemblyCatalog assCatalog = new AssemblyCatalog(this.GetType().Assembly.CodeBase);

AggregateCatalog aggCatalog = new AggregateCatalog(dircatalog, assCatalog);

using (var container = new CompositionContainer(aggCatalog))

{

CompositionBatch batch = new CompositionBatch();

batch.AddPart(this);

container.Compose(batch);

...

I hope this code examples help

 

Developer
Mar 24, 2010 at 5:10 PM

Few things.

1) For the AssemblyCatalog simply pass the Assembly object not the codebase new AssemblyCatalog(this.GetType().Assembly), I don't think this is causing you any issues but there is no reason to do extra loader work.
2) Which of these #1 or #2 work or do both of them work when you enable full permissions?
3) The important question is what is the path variable set to in new DirectoryCatalog(path)? This one would give me some idea of which directory you are actually looking in, also I fully suspect that the resource directories have nothing to do with this because DirectoryCatalog is not recursive.
4) Pointer: Instead of creating a CompositionBatch you can use the extension helper method container.ComposeParts(this). 

Mar 24, 2010 at 5:59 PM

Thanks for your reply.

1) My original code was using just Assembly, but it wasn't working right so i've tried with CodeBase.

2) When I execute this both routines with an Admininstrator User both of them work, otherwise it does not work correctly.

3) the path is something like this: D:\CCC\NT\Framework\trunk\Construction\3.5\ApplicationTest\CCC.FrameworkTest.BasicApplicationTest\Bin

I'm curious about the part you said DirectoryCatalog isn't recursive, because as I've alreade said if I exclude those subdir from my Bin dir the compose goes well. 

Regards,

Developer
Mar 24, 2010 at 7:29 PM

1) Interesting just passing the Assembly should work fine if it isn't then there could be other problems, in fact I would except the codebase to fail more often.
2) So creating only the directory catalog doesn't actually work  if you don't have administrator permission? Something seems very strange here.
3) Yes DirectoryCatalog does not do a recursive search. Also if this is an actual access denied issue the call to Directory.GetFiles in the DirectoryCatalog should throw an exception so I'm starting to wonder if this is actually a permissions issue at all. 

Sorry I'm running out of ideas here. It doesn't sound like a permissions issue because I would expect the DirectoryCatalog to throw an exception but with that said I cannot explain why it works when you grant admin access. Perhaps you can try reproing it by calling Directory.GetFiles yourself and creating an AssemblyCatalog for each "dll" you get back and see if that works, if it doesn't then maybe it will get you closer to finding your problem.

Mar 24, 2010 at 7:32 PM

I'll make some more tests here, and as soon as I have the answer I'll come here to post it. It probably is something weird caused by some directories changes.

Thank you for your support.