This code to generate a a a a a a a a a a a "AggregateCatalog" is driving me batty.



  •                             var catalog = new AggregateCatalog(
                                                    new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)),
                                                    new DirectoryCatalog(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"))
                                                    );
                                _instance = new ExportContainer(catalog);
    

    Look at that fucker.

    Ok, so a little bit of context. I'm trying to write a quick and dirty CLI program to do a data import for a project that normally runs as a website. Part of its plugin identification/loading code runs that little bit up there which, lovely, assumes that GetExecutingAssembly() will return the path to a website (and therefore all the .dlls will be located in /bin.)

    "Hey Blakeyrat," you ask, "what even is an AggregateCatalog?"

    Good question!

    It's a catalog that combines the elements of ComposablePartCatalog objects.

    "Ah. Hey Blakeyrat, what's a ComposablePartCatalog?"

    Good question!

    Obviously, that represents the abstract base class for composable part catalogs, which collect and return ComposablePartDefinition objects. I mean, duh, everybody knows that.

    "Well I don't want to sound dumb, but, what's a ComposablePartDefinition?"

    Good question!

    As any infant can tell you, a ComposablePartDefinition defines an abstract base class for composable part definitions, which describe and enable the creation of ComposablePart objects.

    "Right, of course. One last question: what's a ComposablePart?"

    Good question!

    No, seriously. Good fucking question, because here the trail of breadcrumbs ends with the lovey description: "defines the abstract base class for composable parts, which import objects and produce exported objects"

    Ok, so I have no fucking clue what this code does, or why it needs access to the program's .dlls to do it. What-fucking-ever.

    How do I either trick this code into using the correct path, or tell Visual Studio to make a copy of my project's DLLs and insert them into /bin?

    NOTE: I can't tell Visual Studio to move the entire project into /bin because then "GetExecutingAssmbly" will show up as /bin and this broken code will be looking for /bin/bin.

    Can you believe I told my boss this task would only take two business days? I am a fucking retard.



  • You can put whatever dlls you want into /bin and add this to app.config:

    <runtime>
       <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath=".\bin" />
       </assemblyBinding>
     </runtime>
    

    You get Visual Studio to put them there by writing a post build event (it's in the project properties dialog in the Build Events tab).



  • @Jaime said:

    You can put whatever dlls you want into /bin and add this to app.config:

    I don't want any dlls in /bin. I just don't think I have any other way to fix this.



  • I used the solution I posted one time When I had a Windows Service that also hosted a web-based admin interface. I loaded up ASP.Net with the .Net self-hosting component (System.Web.Hosting.ApplicationHost). All classes that needed to be passed from web page code to service code needed to be defined in a dll loaded into both app domains (two identical dlls wasn't good enough). Since ASP.Net insisted on loading dlls from /bin, all shared code had to be in there.



  • You could act like Windows is a kind of Linux and make a symlink (but call it a directory junction)
    mklink /J bin .
    And then hope it doesn't do recursive scanning of your directory tree... At least it's worth a try.



  • #PROBLEM FUCKING SOLVED.

                // This path has to exist, or the code to look up plugin DLLs will fail
                Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));
    

    Taking another look at the code, it builds AggregateCatalogs from BOTH the Assembly's path, and the AppDomain's path plus /bin. The problem is CLI applications don't have a /bin in their AppDomain path directory, only websites do.

    SO LET'S JUST FUCKING CREATE ONE.

    It doesn't matter that there's no files there, BECAUSE THE STUPID DLLS ITS LOOKING FOR EXIST IN THE ASSEMBLY PATH ALREADY.

    I am king of shitty workarounds.



  • @blakeyrat said:

    AggregateCatalogs

    @blakeyrat said:

    BOTH

    Who could have guessed!

    But seriously, if you don't need the second path, don't add it? Making a folder really is a bad workaround. You don't even need an aggregatecatalog at that point, just the single directorycatalog you actually care about.



  • @Magus said:

    But seriously, if you don't need the second path, don't add it?

    That code is used in more places than my project, is the problem. Making my own copy of the HUGE library to change one line is a bigger WTF than writing a useless directory.



  • This post is deleted!


  • That makes more sense then. As for the whole ComposablePart thing, you're probably better off not thinking too hard on it. It's really a detail of how MEF is implemented, and how it deals with exports internally. The whole idea of MEF is that you only actually deal with your own classes and their attributes, except when you load and unload assemblies.


Log in to reply