Different versions of the same assembly - reflection

I am writing a wrapper for a library that got a drastic change in the API between one version and the other, so I need to create a contract that will allow me to access the two versions of the same API.
This is my project structure:
- Client.dll
- References
- Contract.dll
- Version01.dll
- Version02.dll
- Contract.dll
- IMyService.cs
- Version01.dll
- MyServiceImplementation.cs
- References
- Version01Assembly.dll
- Version02.dll
- MyServiceImplementation.cs
- References
- Version02Assembly.dll
Inside the Project Client.dll I may need to call one implementation of the service or another one, and this is quite fine. The issue is that the assembly loaded into the AppDomain is always the Version02Assembly.dll cause in the bin folder of my Client I always find only the latest version of this dependency.
How can I keep these two libraries referencing a different version of the same assembly?
I hope the question is clear

I haven't ever done it but I think you have two choices -
If possible, give strong names to these assemblies and move them to GAC.
If (1) is not possible, move the assemblies into sub-folders (v1.x & v2.x). Then load the assembly using Assembly.LoadFrom() or AppDomain.Load [ it is possible you might run into type resolution issues, so please read through - http://msdn.microsoft.com/en-us/library/dd153782.aspx#avoid_loading_multiple_versions ]

Related

Symfony 4 and Microservices

Say I'm going to create few microservices: Alpha, Beta, Gamma.
In terms of Application structure using older Symfony version like 2, I'd create a bundle for each service, but bundles are no longer recommended in Symfony 4. So... Should I create separate repositories for every service or still create a bundles in a one App?
If you have different microservices, as in different applications, you will not need bundles. You can keep them in different repositories, but a common practice is to use a so called mono-repository. As the name suggests, with a mono-repository you keep all of the projects in a single repository. This has the benefit that changes spanning all projects can be done more easily and in sync. The drawback is that it requires more effort when managing and might cause additional overhead when building and deploying as it will not be easy to see which service has changed so must likely you rebuild all of them. There are a few books and presentations on mono-repositories you might want to check out. In short, Symfony does not restrict how you manage your services. You can have a single repository for all projects or multiple repositories.
If you want to serve all "services" through the same application, even without bundles, you can do so by using namespaces to separate the logic, e.g. for controllers:
my_app
- src
- Controller
- Alpha
- IndexController
- Beta
- IndexController
This should work out of the Box with the default configuration and even if you deviate you can make things like argument resolvers work by just pointing the configuration to the correct folder. Obviously this will require you to make sure that code is not shared between services should you ever want to extract them into their own application. There are some static code analyis tools that help you with keeping your architecture clean, i.e. make sure Alpha does not use code from Gamma and vice versa.
If you want to separate the apps more clearly by doing something like this:
my_app
- src
- AlphaApp
- ...
- BetaApp
- ...
You can still do that but it will require more manual work and the recipes will not work anymore, requiring you to do manual changes to most configurations and moving around files. How to do it depends on whether you want a shared kernel or a separate kernel for each service, but if you go that route I recommend keeping separate projects in the same repository, as it will probably yield cleaner results and be less work.
You can still create bundles in symfony4 though its not recommended by best practices. see https://symfony.com/doc/current/best_practices/creating-the-project.html

How to use Migration Commands for Entity Framework through User Defined Code

I need to be able to perform all of the available functions that the Package Manager Console performs for code first DB migrations. Does anyone know how I could accomplish these commands strictly through user defined code? I am trying to automate this whole migration process and my team has hit the dreaded issue of getting the migrations out of sync due to the number of developers on this project. I want to write a project that the developer can interact with that will create and if need be rescaffold their migrations for them automatically.
PM is invoking through PowerShell and PS cmdlets (like for active directory etc.)
http://docs.nuget.org/docs/reference/package-manager-console-powershell-reference
The Package Manager Console is a PowerShell console within Visual
Studio
...there is essentially very little info about this - I've tried that before on couple occasions and it gets down to doing some 'dirty work' if you really need it (not really sure, it might not be that difficult - providing you have some PS experience)
Here are similar questions / answers - working out the PS comdlets is pretty involving - in this case it has some additional steps involved. And PS tends to get very version dependent - so you need to check this for the specific EF/CF you're using.
Run entityframework cmdlets from my code
Possible to add migration using EF DbMigrator
And you may want to look at the source code for EF that does Add-Migration
(correction: this is the link to official repository - thanks to #Brice for that)  
http://entityframework.codeplex.com/SourceControl/changeset/view/f986cb32d0a3#src/EntityFramework.PowerShell/Migrations/AddMigrationCommand.cs
http://entityframework.codeplex.com/SourceControl/BrowseLatest
(PM errors also suggest the origins of the code doing the Add-Migrations to be the 'System.Data.Entity.Migrations.Design.ToolingFacade')
If you need 'just' an Update - you could try using the DbMigrator.Update (this guy gave it a try http://joshmouch.wordpress.com/2012/04/22/entity-framework-code-first-migrations-executing-migrations-using-code-not-powershell-commands/) - but I'm not sure how relevant is that to you, I doubt it.
The scaffolding is the real problem (Add-Migration) which to my knowledge isn't accessible from C# directly via EF/CF framework.
Note: - based on the code in (http://entityframework.codeplex.com/SourceControl/changeset/view/f986cb32d0a3#src/EntityFramework.PowerShell/Migrations/AddMigrationCommand.cs) - and as the EF guru mentioned himself - that part of the code is calling into the System.Data.Entity.Migrations.Design library - which does most of the stuff. If it's possible to reference that one and actually repeat what AddMigrationCommand is doing - then there might not be a need for PowerShell at all. But I'm suspecting it's not that straight-forward, with possible 'internal' calls invisible to outside callers etc.
At least as of this post, you can directly access the System.Data.Entity.Migrations.Design.MigrationScaffolder class and directly call the Scaffold() methods on it, which will return you an object that contains the contents of the "regular" .cs file, the "Designer.cs" file and the .resx file.
What you do with those files is up to you!
Personally, I'm attempting to turn this into a tool that will be able to create EF6 migrations on a new ASPNET5/DNX project, which is not supported by the powershell commands.

I want my DotNetNuke modules to work under as many versions as possible while avoiding assembly binding redirection

I am developing DotNetNuke modules and naturally want them compiled before installing or distributing them. In the past I've simply referenced a specific version of DotNetNuke.dll by browsing to the /BIN folder of a local DotNetNuke installation.
This reference allowed me to use the DNN base classes and create my own set of classes upon those. I also use various helper methods throughout the DNN namespaces/classes that I require. (i.e. Make derived classes from their PortalModuleBase, ModuleSettingsBase and use their Localization classes which replace those provided by Microsoft's ASP.NET implementation.)
I've been able to get away with this approach making that direct DLL reference (Copy Local = True, Specific Version = False) because until now I've been installing these modules onto client websites that I maintain. As such, I've kept them on at least the version of DotNetNuke I've been developing on - or newer. Most recently, I was referencing 6.1.3.108 in development.
NOTE: This automatically copies in the following associated DLLs into the /BIN directory of my modules:
DotNetNuke.dll
DotNetNuke.Instrumentation.dll
dotnetnuke.log4net.dll
DotNetNuke.Services.Syndication.dll
DotNetNuke.Web.Client.dll
DotNetNuke.WebControls.dll
DotNetNuke.WebUtility.dll
Installing this onto a DotNetNuke site of a NEWER version worked fine, which isn't a bad start.
What I've been wondering though, is if there is a non-hackish way of making my modules insensitive to the minor, build or revision levels of the DLL?
I realize that it makes it my responsibility to ensure the product (if developed on a "mid range" version) still works on slightly earlier as well as newer versions of the product. That said, I feel I can do thorough testing across those builds. To me this is preferential to having to run the OLDEST major build in development.
Put another way, I'd rather not develop with references to 6.0.0.0 just so it works on 6.x.x.x without extra effort. I'll only do that if someone doesn't have a brilliant way for me to make referencing say, 6.1.3.108 working on slightly earlier or later versions. (Naturally I'm okay with having to make a different module for major version changes, such as 5.x.x.x or 7.x.x.x.)
Thanks in advance!
Instead of referencing the assemblies in the bin folder, keep a copy of DotNetNuke.dll (and any other references) with your source code, and reference it there. Put the oldest supported version there, but develop on a newer site. Set Copy Local=False on the reference so you don't overwrite the newer version, and you should be fine.
In this way, we're able to reference DNN 4.5.3 while developing a module that runs on DNN 6.1.x. I've been using this method for years without any significant problems (except when I occasionally forget to turn off Copy Local and my DNN site mysteriously blows up).
In regards to determining the version of DNN in a class you've subclassed from a DNN one.
Here's what I would do, assuming YourClass inherits from DNNClass, but because you have referenced an earlier version of a property, 'NewProp' doesn't exist. Here's how to do it:
public class YourClass : DNNClass
{
public string NewPropSubstitute
{
get {
string newPropVal = "your default if earlier DNN";
System.Reflection.PropertyInfo pi = this.GetType().GetProperty("NewProp");
if (pi != null)
newPropVal = (string)pi.GetValue(this, null);
return newPropVal;
}
}
}
That's a made-from-memory guess so it might not compile, but you get the idea. You don't necessarily have to get the DNN Version if you want - just try and get the property through reflection - if it's there, implicitly you've got the right version.
Of course this method assumes you can substitute in a value for a later-DNN property (or method) if the DNN version doesn't support it. But that all depends on what you're trying to do.
If you do want to find the DNN Version (version safe and always correct) you can use the code for that which is embedded in my version-safe jQuery inclusion code, linked from this blog post:
Using jQuery in DotNetNuke 5 and 6

Add Project Reference vs Add DLL Reference

I am newbie in .net.Today I have created a sample. In that sample, I have stored data in database using N Tier architecture. If I want to use to Use BL or DAL method in other project(I mean BL method in UI or DAL method in BL), I found two ways.
First one is - Right click on project << Add Reference << Select Project in Project tab
Second one is - Right click on project << Add Reference << Select DLL in Browse tab
Could anyone tell me that is there any difference between both of them as both works same.Is DLL way better then Project Reference.If yes, then what is the benefits?
Thanks in advance.
Regards,
Mohit Kumar.
The correct way to do it is to add a project reference.
one of the most important differences is that a project reference is updated automatically when you change the referenced project.
for example- If you change your DAL method from GetEmployees() to GetAllEmployees() then you can use GetAllEmployees() immediately in your BL class, without compiling your DAL first.
You typically use the project reference when the reference is part of your solution. In this way the relevant latest code is always used.
You will reference an assembly when it is a third party component or not part of your solution. This is somewhat more static as you will be using the code at the version represented by the assembly. So any changes to the assembly will require you to physically overwrite the referenced assembly with the updated dll.
HTH
The differences between the 2 have already been answered, however just to add to that, I think the only difference between the 2 in VS is that if you add project reference it still adds a normal dll reference, except the reference is to the Debug location of the projects binaries (i.e. bin\debug\project.dll), so in essence you could probably just Add Reference in the same way and point straight to the latest compiled dll.
I have came across a very interesting difference between the two approaches, but in the context of having 2 projects, one shared among multiple developers and one private to each developer.
Let us say that the shared VS project is called projectS, and the private project is called projectP
Now if the objective is to have a centralized development, and the developer needs to access source definitions from both projectP and projectS so that pressing "F12" or "Go To Definition" in VS would bring complete definition, then we have to use the Project Reference and not the DLL reference, otherwise pressing F12 would bring the definition from the compiled "metadata" excluding all developer comments and other relevant data.
When adding a Project Reference to projectS from within projectP, VS will resolve references to the files included in projectS and referred to from projectP using the source definition in projectS, and not from "metadata" of the DLL associated with the referenced project (ProjectS.dll). Still, the projectS.dll will be included in the References folder and Development time, Execution time will be OK.
When adding a DLL reference, VS will resolve references from "metadata" stored in ProjectS.dll, even if the Referenced Project was added to the Solution of projectP as an "Existing Project". This would allow Execution time to be OK, however, Developer will not be able to press F12 and go to Source definition in projectS, he/she will have to do this manually from the solution search area.

Visual studio refactoring - move class to assembly

I'm looking for the simplest (and most complete) mechanism to move a class from one to another assembly with reference (dependency) fixing capability.I know some manual ways to do that like :
- use built-in move rename, then cutpaste, multiple save ...
- use resharper rename namespace, cutpaste , the same as above
but with the problem is the same with those : in a web environment (namely ASP.Net) almost all of the references (for user controls for example, let's suppose with assembly name in their path for a virtual path provider scenario) are coded a string references (not to mention the configuration files and other external reference sources) - unfortunately even resharper doesn't found all. Other problem is with the designer files - you know they're generated on at least save action accordingly to the specifications in control and sometimes they're somehow mixed with the rename action I mean here's the old there's the new assembly name etc.
Thanks in advance,
Nicolai
If you are using Resharper try the Test Driven Development
It Allows a number of refactors like that.

Resources