How do I use automapper with System.AddIn? - c#

In the System.AddIn (aka MAF) pipeline adapters, there is a lot of manual copying of values from one DTO type to another - from HostView types to Pipeline Contract types and from Pipeline Contract types to AddIn view types (and back again). This seems like an ideal situation to use automapper.
However I am unsure as to the correct way to use and package 3rd party assemblies in the HostView and AddInView adapters, especially when AddIn activation is in a separate AppDomain.
I tried the following:
add nuget reference for automapper to AddIn adapter project and create the mapping profiles within. (I used a static ctor to the adapter that initializes the profiles cos MAF is responsible for instantiating the adapter.)
Counter-intuitively, to get the pipeline to locate and activate AddIns supported by the adapter, I had to ensure that the automapper DLL lived in the bin dir of my Host - having the automapper DLL in the "AddInAdapters" folder beside the actual adapter DLL had no effect.
With this arrangement, I was able to find and activate the AddIn on my dev box (win 7). But the exact same binaries would not work on Server2008R2. (I know, I know: I don't control the choice of development or server OS)
We are using (and targeting) .Net 4.5.1 - yep, it's on desktop and server. We are using automapper 2.2.1 - nope, it's not in the GAC of my dev box
Where should 3rd party assemblies used by Adapters be located (both AddIn side and Host side). Especially when considering AppDomain isolation
Why would the above arrangement work on Windows 7, but not 2008R2?

On the host side, it should live in the root output directory of your application. All of the host dlls are loaded in your app domain and the assembly resolver will look in the location of your running assembly for the automapper dll.
On the Addin side, it should live in the addin adapter directory. The addin adapter and addin view are loaded into the new app domain and require their own copy of this dll.
One thing to be careful with when using third party libraries anywhere in your pipeline is it can make versioning your pipeline painful. If you are loading multiple versions of your pipeline to allow for V1 and V2 addins to still work, if they depend on different versions of an assembly, you may run into problems in reconciling this. If you don't care about pipeline versioning, then this is less of a concern.

Related

Automate Enterprise Architect Configuration

We are using Enterprise Architect for our models.
EA can be integrated with version control system, for that, it is required to set configuration from EA to the directory in SVN folder- in which the XMI files of packages will be stored.
The configuration settings process is a long and annoying process which we would like to be done automatically.
Is there a way to do this programmatically?
UPDATE: This is the window which requires the manual configuration for each machine.
Yes, there is. The API does not support selecting version control provider etc, but it does support adding/removing packages to/from version control and checking them in and out once the provider is set.
The methods are in the Package class (in the help file under Automation and Scripting -- Enterprise Architect Object Model -- Reference -- Repository Package -- Package Class):
VersionControlAdd()
VersionControlCheckin()
VersionControlCheckinEx()
VersionControlCheckout()
VersionControlGetLatest()
VersionControlGetStatus()
VersionControlPutLatest()
VersionControlRemove()
VersionControlResynchPkgStatus()
Repository.VersionControlResynchPkgStatuses() resynchronizes all version-controlled packages, but that's the only project-level version control method in the API.
You don't have to write an Add-In if it's a one-off thing. A stand-alone application has access to the Object Model API, whereas an Add-In (which is integrated into EA) also has access to the Add-In Model API (see Automation and Scripting -- Enterprise Architect Add-In Model).
The Add-In Model API fires a number of events when model elements are created, updated, etc, but no events are triggered by version control changes. So if you only need to add a number of packages to the version control repository, a stand-alone application can do that.
Have you referred to the best practices prescribed by Sparx? http://www.sparxsystems.com/WhitePapers/Version_Control.pdf
Whilst I agree it could be a time-consuming process to setup version control for the first time, there are several tricks which could make it less cumbersome.
E.g. COnfiguring the packages (or branches) in one model and then sharing the same to the rest of the team, and just letting them specify the Working Copy of the rewpository.
PS - It is also best not to interfere with the package structure in your SVN folder, and let EA take care of the same

Test compatibility between DLL in .NET

I'm working with Visual Studio 2010 and WinForms, .Net 4.0 (C#). I'm building an application with a lot of DLL (150). When I provide the application to my client, it's :
The Executable (.exe)
Dll files (.dll)
Each Dll is related to a module of the application, for example :
Ado.dll (provide access to database)
AccesManagement.dll (this module allows to manage users in the application)
Import.dll (this module allows the user to import data to the application)
etc.
When my client find a bug in the application, I correct it and I provide him impacted DLLs (in order to avoid him to test all the application). It can be for example the Import Dll.
The thing is, after some deliveries, we can have compatibility problems between Dll (a method that doesn't exist anymore in a new DLL for example). To avoid this problem, I would like to find a tool capable of checking compatibility between differents DLL.
I would like something like :
I specify the directory of the program to analyse (executable + Dll)
I launch the analyse
The program tells me for example : Error between Import.dll and Ado.dll, there is a class xxx in Import.dll expecting a method named xxx in the class xxx of Ado.dll
I've found some tools able to compare two versions of a Dll and provide added and removed members (Libcheck, ApiChange), but it's too complicated for me to do that because there are to many changes.
I think you may have a configuration management problem here -- at least as much as you've got a "compatibility" problem.
I'd recommend you find a way to track what versions of which assemblies each of your customers is using so that (1) you know what they're using when you decide what to ship, and (2) when they report bugs, you can replicate their setup (and thus, replicate their bug). If that sounds like a lot of work, it is. This is why a lot of software development shops take steps to ensure that there's a limit to the variation in setups among customers. It's nearly certain that you'll end up with some variation from customer-to-customer, but anything you can do to manage that problem will be beneficial.
Beyond the process implications, if you really need to create a "pluggable" environment, you probably need to create some interfaces for your objects to control the points where they connect, and you should probably look at Microsoft's Managed Extensibility Framework (MEF). MEF can help you manage the way objects "demand" behaviors from other objects.
I finally found a solution to my problem.
Since I'm :
Using SourceSafe and adding labels with the version of the application I'm building
Tagging each of my DLL with the version of the application
I built a program which is capable of :
Opening each Dll of a folder to read the version of the application in it
Getting from SourceSafe each project for the version specified in the DLL (With the functionnality "Get Label")
Then I just have to build the projet. If there is any compilation error, there is a compatibility problem.
This solution can avoid big compatibility problems, but you can still have compatibility problems which can't be seen with a compilation...

How can C# use a legacy DLL simply without registration(regsvr32)

Situation
I run a build system that executes many builds for many project. To avoid one build impacting another we lock down the build user to only its workspace. Builds run as a non privileged users who only have write ability to the workspace.
Challenge
During our new build we need to use a legacy 3rdparty DLL that exposes its interface through COM. The dev team wants to register the build(regsrv32.exe) but our build security regime blocks this activity. If we relax the regime then the 3rdparty DLL will impact other builds and if I have two build which need two different versions I may have the wrong build compile against the wrong version (a very real possibility).
Question
Are there any other options besides registration to handle legacy DLLs which expose their interface via COM?
Thanks for the help
Peter
For my original answer to a similar question see: TFS Build server and COM references - does this work?
A good way to compile .NET code that references COM components without the COM components being registered on the build server is to use the COMFileReference reference item in your project/build files instead of COMReference. A COMFileReference item looks like this:
<ItemGroup>
<COMFileReference Include="MyComLibrary.dll">
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMFileReference>
</ItemGroup>
Since Visual Studio provides no designer support for COMFileReference, you must edit the project/build file by hand.
During a build, MSBuild extracts the type library information from the COM DLL and creates an interop assembly that can be either standalone or embedded in the calling .NET assembly.
Each COMFileReference item can also have a WrapperTool attribute but the default seemed to work for me just fine. The EmbedInteropTypes attribute is not documented as being applicable to COMFileReference, but it seems to work as intended.
See https://learn.microsoft.com/en-ca/visualstudio/msbuild/common-msbuild-project-items#comfilereference for a little more detail. This MSBuild item has been available since .NET 3.5.
It's a shame that no-one seems to know anything about this technique, which to me seems simpler than the alternatives. It's actually not surprising since I could only find just the one above reference to it on-line. I myself discovered this technique by digging into MSBuild's Microsoft.Common.targets file.
There's a walkthrough on registration-free COM here:
http://msdn.microsoft.com/en-us/library/ms973913.aspx
And excruciating detail here:
http://msdn.microsoft.com/en-us/library/aa376414
(the root of that document is actually here: http://msdn.microsoft.com/en-us/library/dd408052 )
Also, for building in general, you should be able to use Tlbimp or tlbexp to create a TLB file that you can use for building, assuming the point of registering is just to be able to compile successfully, and not to run specific tests.
Installation tools such as Installshield can extract the COM interfaces from the DLLs and add them to the registry. It can also use the self-registration process of the DLL (which I believe is what regsvr does), but this is not a Microsoft installer best practice.
in .NET COM is normally done thru Interop in order to register .DLL in .NET they are called Assemblies and that can be done several ways.. by adding references via VS IDE at the project level, or writing code that Loads and unloads the assembly.. by .Config file that haas the reference to the assembly as well as the using of that reference within the project... GAC.
If you have access to the 3rd party .DLL's you can GAC them, and reference them in your project
you can add a using to your .cs file header as well as add the reference to the project by right clicking on reference --> add Reference ...
you can also do the above step as well as set the copy local = true in the properties for that .dll.. I hope that this gives you some ideas.. keep in mind that .NET assemblies are Managed code so there are several ways to Consume those 3rd party .DLL's using other methods within C# like LoadFromAssembly ect..
Thanks for all the help.
We changed from early-binding to late-binding because we never really needed the DLL at compile time. This pushed the registration requirement from the build server to the integration test server (where we execute the installer which handles the registration). We try to keep the build system pristine and have easy-to-reset integration systems.
Thanks again
Peter

How to create a generic use library

I have an image editor user control(c# .net v2.0). Its used in thousands of computers as an activex component. I want the component also be available for windows forms and possible other uses.
For activex usage i add <object> tag in html code and call the component with clsid(a static guid). So if i build and distribute a newer version it works without changing any client code.
I want windows forms to be able use the same distributed libraries. And they should not reference a specific version so i can update the component without changing the programs that use it.
I use regasm to register for com. But i dont know how to reference it from visual studio(like referencing with clsid?)
May be in visual stuido when i choose add reference and select COM tab i shuld see my component in the list.
note: i tried to add the assemly to the global cache using these lines but it did not work out-or i coulnt understand if anything has changed :)
"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\tlbexp" ImageEditorComp.dll /out:ImageEditorComp.tlb
regasm /tlb:ImageEditorComp.tlb ImageEditorComp.dll
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\gacutil" /I ImageEditorComp.dll
Any suggestions appreciated,
Regards
This is not possible, you'll invoke the infamous and dreaded DLL Hell problem. A stone cold hard rule in COM is that you have to change the [Guid] attribute values on public interfaces when you make a breaking change in either the publicly visible interfaces or the implementation of them. Changing the guids ensures that you don't overwrite the registry keys of an old version of your component when you use Regasm.exe. Existing programs that use your component and were not recompiled to use the latest version will continue running without problems. The typical outcome of DLL Hell is a nasty hardware exception like AccessViolation, very difficult to troubleshoot.
None of which applies in your specific case here. There is no point in trying to use the component through COM. It is a .NET assembly, just add the reference to it directly. The IDE will in fact stop you from adding a reference to the interop library. But not the .tlb. The GAC keeps you out of DLL Hell, assuming you properly increment [AssemblyVersion].
I figured out a solution.
To explain step by step:
1- Create the component with all needed properties for com.(Sign the assembly, use interfaces for com, make assembly com visible)
On the client machine
2- Register the assembly with regasm(i recommend adding safety flags too).
3- Add the assembly to the global cache using gacutil(or msi installer)
I figured out when you call a specific version of an assembly gac is searched in the first place so if its installed in GAC, referenced codebase path is never used.
When using as activeX you address the component with GUID. Since regasm adds the assembly name and version the GUID is representing, web browser directly uses component from GAC.
When using from a desktop application, reference the assebmly directly and set copylocal property to false. Similarly, in the client machine windows will find the assembly located at GAC itself.
Here is a useful link about the subject.
http://www.simple-talk.com/dotnet/visual-studio/build-and-deploy-a-.net-com-assembly/
Hope it saves other peoples time :)

In .NET, is there a need to register the DLL?

Is it necessary to register a compiled DLL (written in C# .NET) on a target machine.
The target machine will have .NET installed, is it enough to simply drop the DLL onto the target machine?
I think you're confusing things a little. Registering a dll has never been needed in order to use it.
Using a dll requires only to load it (given a known location or if the library is in the system path) and get the address of the function you wanted to use.
Registering the dll was used when distributing COM or ActiveX objects which need to add certain entries to the windows registry. In order to use a COM service (for example) you need to reference a GUID — that is, a unique identifier — which allows you to get a handle to the dll that implements the service (or provide access to it). Sometimes you can make reference to a fully-qualified name and get the same results.
In order for all that to work the dll needed to be registered. This "registration" process just creates several entries in the registry, but mainly these two: one associating a GUID with the location of the dll (so that you can reference it through the GUID without knowing where is it exactly located) and a second one associating the full name with the GUID. But again, this is just for COM or ActiveX objects.
When you develop an application in .NET, the libraries referenced on your project are automatically loaded when they're needed without you having to worry about locating or loading them. In order to to that, the framework checks two locations for the referenced libraries.
The first location is the application path.
The second location is the GAC.
The GAC (Global Assembly Cache) allows you to effectively register a dll to be used throughout the system and works as an evolution of the old registering mechanism.
So basically you just need to put the dll in the same folder of the application.
You need to "drop" it into a directory where the application needing it will find it.
If there are multiple applications, or you want to "drop" the file somewhere other than the application directory, you generally need to either adjust the PATH variable, or register the assembly in the Global Assembly Cache (GAC).
It is usually enough to drop the dll into the folder of your app on the target machine.
If the dll must be available to other applications then you may want to consider the GAC.
If you wish to access the assembly via com+. An example would be using a type defined in a .NET assembly from a non .NET application, such as a VB6 winforms app.
If you plan on accessing the assembly from another .NET application, you don't have to do anything. If your assembly has a strong name, it probably is a good idea to drop it in the GAC. Otherwise, just drop it in the directory of the application that will be referencing it.
One of the great selling points of .NET for the Windows platform when it came onto the scene is that by default, .NET assembly DLLs don't have to be registered and can be consumed privately by an application by merely putting them in the same folder as the EXE file. That was a great stride forward because it enabled developers to avoid the fray of DLL/COM hell.
Shared DLL/COM modules proved to be one of the greatest design mistakes of Windows as it lead to instability of applications that users installed. Installing a new app could well screw up an app that had been working just fine - because the new app introduced newer versions of shared DLL/COM modules. (It proved in practice to be too much of a burden for developers to properly manage fine-grained version dependencies.)
It's one thing to manage versions of modules with a build repository system like Maven. Maven works extremely well doing what it does.
It's an entirely different matter, though, to deal with that problem in an end-user runtime environment spread across a population of millions of users.
The .NET GAC is by no means a sufficient solution to this age-old Windows problem.
Privately consumed DLL assemblies continue to be infinitely preferable. It's a no-brainer way to go as diskspace is extremely cheap these days (~$100 can by a terabyte drive at Fry's these days). There is nothing to be gained with sharing assemblies with other products - and yet company reputation to loose when things go south for the poor user.
Actually there is NO need to register a dll in .NET on the target machine.
If you reference a .dll in your application, click on the referenced .dll under references in your project, look at the properties and set Isolated to TRUE.
This will now automatically include this .dll in your project and your application will use the copy of the .dll included in your project without any need to register it on the target system.
To see a working Example of this look here:
http://code.msdn.microsoft.com/SEHE
The .dll in question will need to be registered on the system where you build your application for this to work properly. However once you build your project, there will not be any need to register the .dll in question on any system you deploy your application or program.
An additional benefit of using this method, is that even if in the future, another .dll is registered with the same name on the target system in question, your project will continue to use the .dll you deployed with. This is very handy where a .dll has many versions and you wish to maintain some stability, like using the one you tested with, yet all other applications will use the registered .dll unless they use the isolated = true method as well.
The example above is one of those cases, there are many versions of Skype4COM which is a Skype API .dll and can change often.
This method allows the above example to use the API .dll that the project was tested with, each time a user installs a new version of Skype, it is possible that a modified version of this .dll is installed.
Also, there are some Skype clients that do not install this .dll, the business version of the Skype client for example, is smaller, and does not include this .dll, so in this case, the project does not fail on that .dll missing and not being registered because it is included in the project as isolated = true.
An application can use a .NET dll by simply having it present in the same folder with the application.
However if you want other third-party applications to find the DLL and use it they would also have to include it in their distribution. This may not be desirable.
An alternative is to have the DLL registered in the GAC (Global Assembly Cache).

Categories