Resolve dependencies with Castle Windsor using MEF in Visual Studio 2010 addin - inversion-of-control

I was wondering if there were best practices about using Castle Windsor with Visual Studio 2010 addin, which uses MEF internally to instantiate its controls, such as the IWpfTextView.
All the dependencies are registered when the VsPackage is created. How can I later resolve those dependencies when the IWpfTextViewCreationListener is created via MEF, sometime later? Should I expose the container as a singleton and access it, or is there a better way?
Edit Here's what I'm trying to accomplish. When the VsPackage is created, Windsor is wiring all the dependencies, which is, of course, what it does great.
My addin is a "Editor Adornment" type of extensibility, so after the solution is loaded and a code file is opened, I get a callback to my class which inherits IWpfTextViewCreationListener (and exported with [Export(typeof(IWpfTextViewCreationListener))] via MEF (which is done automatically by Visual Studio).
This happens in another context, that is, I don't have access to the VsPackage from this class, and any dependencies I need will not be initialized. So at this point I'm not sure how can I get those dependencies that were wired previously by Windsor.
Hope this makes it clearer.
(You can try creating your own extensibilty project using File | New Project | Visual C# | Extensibility | Text Editor Adornment, for example, to see how (and when) the TextAdornment1Factory is created.

Related

MEF Plugin update strategies for winforms

I'm developing an extensible application with MEF. The application will have many types of plugins to collect and process data in different ways.
I'm thinking about building a versioned online repository for the plugins, that will enable the user to download new versions of the plugins when they become available.
It would be nice if MEF could load different versions of the same plugin simultaneously, though from what I understand this isn't possible (correct me if I'm wrong).
So I've resigned myself to the fact I will need to update the plugin and archive the previous version.
What would be the best strategy for doing this?
Example 1
The Application downloads a new version of a loaded running plugin. I can't place the plugin in the plugin directory as there is already DLL with the same name. So I could rename the new plugin with a version suffix. I can't load the same assembly, so I guess I'll have to force a restart. So on restart, it achieves the old plugin and loads the new one.
--- This seems solutions seems a little messy
Example 2
The Application downloads a new version of a loaded running plugin.
The plugin is encased in some type of installer.
The installer closes the host gracefully and archives the existing plugin.
The installer installs new plugin and restarts the host app.
--- this also seems a little messy
I am seeking any correction of my assumptions, or any insight into a successful strategy to my achieve my goal.
The .NET Framework has a fearure called Shadow Copy which allows you to update loaded assebmlies. Basically it copies the assemblies to a temp folder and loads them from there. This way the assemblies located in your application's installation folder will not be locked by the OS and you will be able to replace them. ASP.NET, unit test framweorks and many other applications use shadow copying.
To enable this feature you will need to load your application in a new AppDomain since you cannot enable shadow copying on the main AppDomain. You can create a simple loader that will create an AppDomain and execute your application there. This is very straight forward. For an example of MEF + Shadow Copy have a look at Glenn Block's Way of MEF and in particullar the PartUpdatesInPlace sample.
Now as far as versioning is concerned you will need to be able to have two or more versions of an assembly loaded at the same time in the same application domain. There are two ways to do this:
Strong named assemblies in the GAC.
Assemblies with the version included in their name (like Plugin.v1.dll). Strong naming is optional in this case but a good idea nonetheless. The advantage of this approach is that two or more versions of a plugin can coexist in the same directory.
Have a look at this answer for an example of MEF + Versioning.
You can even use the recomposition feature of MEF and have your plugin container updated after:
A new plugin assembly is added
A plugin assembly is deleted
A plugin assembly is replaced
Have a look at this question for an example.

Using Soap in Shared Mono Library for WP 7 and Android

I'm currently working on an shared library based on mono, where I want to put as much business logic of my app as possible.
I used this helpful tutorial.
I managed putting the whole logic for rest-requests in this shared library, but now I'm stuck with soap.
I used the wsdl command of mono to generate Client Stubcode from my wsdl (as described here http://www.mono-project.com/Web_Services).
When I put the generated class to my C# library, which is the root project of my shared library, there is a warning that the Reference to System.Web.Services cannot be found.
So I included the System.Web.Services.dll manually.
For the Android Library Project I added a Reference to ...\Reference Assemblies\Microsoft\Framework\MonoAndroid\v1.0\System.Web.Services.dll. It compiles without warnings.
But now it comes to the Windows Phone Library Project.
There is no System.Web.Services.dll for WP 7.5, right? I tried with the Mono-Touch dll but it gives me a lot compilation Errors.
Someone knows how I can get out of this?
I actually had some issues with the generated WSDL myself. Turns out that the classes that were generated through the "Create Web Reference" piece of Visual Studio inside of a Mono for Android project ended up causing some big issues when connected to a WCF Web Service. Not sure where I ran into this information, but this is what I ended up doing.
What you need to do is manually create a Service Reference using the SILVERLIGHT SVCUtil.
On my development system it was located here:
C:\Program Files (x86)\Microsoft SDKs\Silverlight\v3.0\Tools
I called it with the below command line:
slsvcutil.exe http://localhost/<path to WCF service endpoint>/service.svc /directory:"<temp directory to store generated cs file>" /noConfig /namespace:"*,<Full namespace of the generated class>"
That will actually generate a CS file that is saved into the path specified by the /directory tag above. Copy that generated cs file to your project directory and then include it in the project.
The problem that I was having that forced me to look for another option was that I was able to pull the data properly using the WSDL generated through the "Add Web Reference" option in Visual Studio, but as soon as I tried to pass the data back up the wire to the web service, everything blew up. Using the Service Reference generated by the Silverlight Service Util actually generated all the code properly for Async operations and after learning how to properly manage those Async operations everything works like a dream.
Since you are generating this new WSDL using the Silverlight Utility, it should work just fine through Windows Phone 7. I believe that the DLL to reference for all of this is the System.ServiceModel dll.
I wish I could remember where I ran across this information, as I would like to give the original author credit, but unfortunately, I don't recall that.
Hope that helps out!
Chaitanya Marvici

Windows Workflow 4 Designer error using custom activities with custom libraries

I built a custom activity referencing a custom library. When I drop my custom activity into a Windows Workflow 4 designer, I get this error:
Workflow Designer encountered problems with your document
Please check the document for invalid content, namespaces, references or reference loops
System.IO.FileNotFoundException: Could not load file or assembly 'my custom libary...'
I'm using Visual Studio 2010.
I've tried adding the library to the GAC, cleaning and rebuilding but still get the error. Any ideas? Thanks.
Be sure that the custom Library is added as a reference to your Rehosted editor. If not you can you can try is manually load your custom library assembly into the AppDomain.
AppDomain.CurrentDomain.Load(AssemblyLocation_you_pass_in);
Hope this helps.

Visual Studio 2010 Publish Web feature not including all DLLs

I have an ASP.NET MVC 2 application.
Web project contains a reference to SomeProject
SomeProject contains references to ExternalAssembly1 and ExternalAssembly2.
SomeProject explicitly calls into ExternalAssembly1, but NOT ExternalAssembly2.
ExternalAssembly1 calls into ExternalAssembly2
When I perform a local build everything is cool. All DLLs are included in the bin\debug folder. The problem is that when I use the Publish Web command in Visual Studio 2010, it deploys everything except ExternalAssembly2.
It appears to ignore assemblies that aren't directly used (remember, ExternalAssembly2 is only used by ExternalAssembly1).
Is there any way I can tell Visual Studio 2010 to include ExternalAssembly2?
I can write a dummy method that calls into ExternalAssembly2. This does work, but I really don't want to have dummy code for the sole purpose of causing VS2010 to publish the DLL.
None of these answers are sufficient in my mind. This does seem to be a genuine bug. I will update this response if I ever find a non-hack solution, or Microsoft fixes the bug.
Update:
Doesn't seem promising.
https://connect.microsoft.com/VisualStudio/feedback/details/731303/publish-web-feature-not-including-all-dlls
I am having this same problem (different assemblies though). If I reference the assemblies in my web project, then they will get included in the publish output, but they should be included anyway because they are indirect dependencies:
Web Project ---> Assembly A ---> Assembly B
On build, assemblies A and B are outputed to the \bin folder. On publish, only assembly A is outputed to the publish folder.
I have tried changing the publish settings to include all files in the web project, but then I have files in my publish output that shouldn't be deployed.
This seems like a bug to me.
I had the same problem with VS2010 and a WCF Service Application.
It turns out that if your (directly or indirectly) referenced DLL's are deployed to GAC, the VS publishing feature excludes them. Once I removed the assemblies from GAC, publishing feature started working as expected.
I guess VS is assuming that if your assemblies can be located in GAC on the machine you build, they will be located in GAC on the target machine as well. At least in my case this assumption is false.
My tests show that the external assemblies get published when I have a reference on them in the web project. I do not have to write any dummy code to make it work. This seems acceptable to me.
I agree with Nicholas that this seems to be a bug in visual studio. At least it escapes me what the reason for the behavior could be.
I have created this issue as a bug on Microsoft Connect. If anyone experiencing it could vote it up https://connect.microsoft.com/VisualStudio/feedback/details/637071/publish-web-feature-not-including-all-dlls then hopefully we'll get something done about it.
If you go into the ExternalAssembly2 reference property list and change the "Copy Local" to "True" i think that might solve your issue.
I don't know if you are watching this still but I found the solution (I had the exact same issue) via this MSDN article. Under "build action" for the file choose "Content" that should include it in the list of files publish brings over.
I have created a new Connect bug here https://connect.microsoft.com/VisualStudio/feedback/details/731303/publish-web-feature-not-including-all-dlls
I've also attached a solution and detailed steps to reproduce this issue. Lets hope this time they won't close it as Can't Reproduce.
Vote for this connect issue if you experience the missing dll problem.
Copy local did the trick. I had an issue that the Newtonsoft.Json assembly get included in the deploymeny package. Copy local was set to false.
I am experiencing the same type of issue with a web project. I have a web project that references assembly A which references assembly B. It worked fine for some time but today it was broken. I did a rebuild of the solution and this time it deployed everything correctly.
I had this same problem today. I published my web project and realized that not all of the reference DLL's were there. In particular, the indirect DLL references.
It turns out that the directory in which I was publishing to was out of disk space (network share). I had just enough space to publish all the files except for few indirect reference DLL's. The sad part is that VS08 didn't throw any errors. It just published the files are usual. I cleared out some HDD space and everything worked fine.
I didn't find the HDD space issue until I tried to manually move the DLL's over.
in my case it is quite tricky.
Reference to ExternalAssembly2 is not required to Build the project but vital for run-time since we use reflection to configure Unity container.
So, I delete the reference - build the project successfully, but get run-time error.
If I preserve the reference I can Build and Run the application but I cannot Publish it with ExternalAssembly2 - get run-time exception as well.
This is happen because of internal VS2010 assemblies optimization.
So, what we can do here?
1. Put some unrequired peice of code to use any ExternalAssembly2's class.
2. escape from reflection and use static assemblies linking.
Hope this helps to smbd.
I got the same problem and this is a VS2010 bug if there's a reference link like:
Web Project --> custom project --> assembly1 -->(indirectly) assembly2.
For now I find if I reference the Assembly1 in the web project, then assembly2 is included in the bin folder.
So I had to add an additional reference link like:
Web project --> assembly1 -->(indirectly) assembly2.
Then VS can recognize assembly2 and include its dll file in publish action.

vb6 xcopy deployment

Can any one tell me how to convert an legacy application which is vb6 ( COM dll's ocx and exes) to use Regfree COM .
I tried opening the dlls in visual studio and created manifest file, but some of the dlls it is giving error.
Is there any tools out there which will help me to do this process?
I tried a tool from codeproject which is called regsvr42, which is not creating the manifest fully.
I used tools like PE explorer where I get all the typelib information , but converting them into manifest files is too difficult.
We have started migrating that to .NET, for some months we have to deploy it, it will easier if it is xcopy based deployment.
To create manifest files you can try to use Make My Manifest from http://mmm4vb6.atom5.com/.
EDIT The MMM website is down. I see here that the author was having trouble with their hosting and has provided another location to get Make My Manifest - download it here.
If you can control creation of objects you can use DirectCOM from http://www.thecommon.net/10.html
Keep in mind that if one of used DLLs or OCXs is creating other COM objects dynamically with CreateObject calls, that reference will not be stored in vbp project file and you won't get full manifest file. Probably you will have to catch object creations while the application is running. Depends.exe application can profile running application and report all used dlls. I don't know if there is tool that can find additional COM related information.
There is an excellent walkthrough of what to do in this article on MSDN: Registration-Free Activation of COM Components: A Walkthrough.
Make My Manifest can accomodate late binding as well as early binding. You simply have to add the references to the late-bound dependencies manually, by file location or by ProgId.
You might look at http://mmm4vb6.atom5.com/mmm-demo-1248.html for additional help in using the utility.
MakeMyManifest is well spoken of as an automatic tool for creating manifests for VB6 projects, haven't tried it myself.
DirectCOM also has fans, again I haven't tried it.
EDIT The MMM website is down. I see here that the author was having trouble with their hosting and has provided another location to get Make My Manifest - download it here.
There is a semi-automatic technique. You can create the manifests with Visual Studio 2008 (you can use a free version like Visual Basic Express Edition). Then make a couple of edits by hand to make the manifests suitable for use from VB6. See this section of this MSDN article for step-by-step instructions - ignore the rest of the article which is about ClickOnce.