Provide MoreLinq as a Portable Class Library
Closed this issue · 21 comments
To widen the applicability of MoreLinq, it would be great if the library could
also be provided as a Portable Class Library. I have done a first examination
of what would be required in order to build a PCL out of MoreLinq, and my
findings can be found in this answer to a StackOverflow question:
http://stackoverflow.com/a/13700766/650012
Original issue reported on code.google.com by cureos...@gmail.com
on 4 Dec 2012 at 10:28
I have created a clone in case anyone is interested in retrieving the Portable
Class Library adaptation, at http://code.google.com/r/cureosab-morelinq/ . You
can find the relevant commit here:
http://code.google.com/r/cureosab-morelinq/source/detail?r=09bfaecbac3547bf8f079
5d3217d3229d0c03627
Original comment by cureos...@gmail.com
on 4 Dec 2012 at 8:17
Any update on this issue?
The current state of the source code (rev. ac22aac7615b, July 9 2014) is ideal
for a Portable Class Library.
It is very easy to create a profile 344 PCL library in e.g. VS2013.2 which will
target practically everything of interest: .NET 4 and higher, Windows 8 (Metro)
and higher, Windows Phone Silverlight 8 and higher, Windows Phone 8.1,
Silverlight 5, Xamarin.Android, Xamarin.iOS.
You only need to enter these compilation symbols in the .csproj file:
NO_SERIALIZATION_ATTRIBUTES;NO_EXCEPTION_SERIALIZATION;NO_TRACING
(3 files affected),
change the signature in the invocations of the ArgumentOutOfRangeException
constructor in Repeat.cs and Subsets.cs (one of the PCL targets, Silverlight 5,
does not support the "string, object, string" constructor, but it can be easily
replaced with the "string, string" constructor),
and, finally, exclude "ToDataTable.cs" from the PCL project, since the
System.Data namespace is only available in the .NET target.
It would be terrific if you could include a PCL project in the MoreLinq
solution, and also publish a build of it on NuGet.
If you do not have the time or incentive to do this, would it be OK if I
published such a PCL on NuGet instead?
Many thanks in advance!
Anders Gustafsson, Cureos AB
https://www.nuget.org/profiles/cureos
Original comment by cureos...@gmail.com
on 4 Aug 2014 at 11:24
Two more things:
1) I have now updated my MoreLINQ clone at
https://code.google.com/r/cureosab-morelinq/ with the changes that I outline in
the comment #2 above, so it would be super easy for you to merge these changes
into the main line of MoreLINQ.
2) I referred to an incorrect PCL profile in comment #2 above; the relevant
profile would be 328.
Original comment by cureos...@gmail.com
on 4 Aug 2014 at 12:24
Original comment by azizatif
on 5 Aug 2014 at 5:46
- Changed state: Accepted
@cureos.ab Can you enable reviews on your clone?
Original comment by azizatif
on 5 Aug 2014 at 5:49
Thanks for considering this request, @azizatif. I have now enabled reviews on
the clone. While I am at it, I can also mention that I ran the unit tests
(excluding ToDataTable and Trace tests) referencing the portable library, and
all tests passed.
Original comment by cureos...@gmail.com
on 5 Aug 2014 at 6:20
Original comment by azizatif
on 5 Aug 2014 at 4:26
- Changed state: Started
@cureos.ab:
> would it be OK if I published such a PCL on NuGet instead?
Submitting a nuspec for the portable version to your clone would certainly help
speed things up.
Original comment by azizatif
on 5 Aug 2014 at 4:34
- Added labels: Milestone-Release1.0
Hi again Aziz,
I have now updated the portable project according to your requests. I have also
added a unit test project for the portable library and a nuspec file based on
the nuspec file for the original library. Please take a look at this to see if
it fits.
Best regards,
Anders
Original comment by cureos...@gmail.com
on 5 Aug 2014 at 9:06
+1 for adding the unit test project too. See my review:
https://code.google.com/r/cureosab-morelinq/source/detail?r=1c90b1c22fbbc4d2887e
187a33c390cc808a649d
Original comment by azizatif
on 6 Aug 2014 at 5:50
@cureos.ab Based on review comments[1] and an attempt to fix the clone history,
I'm attaching a Mercurial bundle with a v1 branch. You can start with a new
clone and import the bundle by running:
hg pull -u bundle.hg
You should then switch to v1 branch, work on there and push to your clone and
we can take it from there.
Let me know if anything is confusing.
[1]
https://code.google.com/r/cureosab-morelinq/source/detail?r=3e0e2f80c24c4c2194bc
37404e6f5f733fc8fcdf
Original comment by azizatif
on 8 Aug 2014 at 5:52
Attachments:
@azizatif Based on your bundle, I have now created a new clone with a cleaner
commit history. You'll find it here:
https://code.google.com/r/cureosab-morelinq-portable/source/list
I have added a tag "v1.0-portable" on which the PCL NuGet build could be based,
and I have merged the "v1.0" changes into the "default" branch.
The project GUID:s are all different, i.e. MoreLinq and MoreLinq.Portable have
different GUID:s etc. As I mentioned in a previous code comment, I think it
makes sense to have it this way, since the .NET and PCL projects are
functionally different. (And Visual Studio does not accept it either if I keep
both projects in the same solution...)
When it comes to assembly identity equivalence, I believe that the important
things are that the strong names are equivalent, i.e. that the assemblies have
the same name and are using the same .snk file.
Please have a look at my new clone to see if there are any further issues that
you want me to deal with before the PCL NuGet package is ready for publishing.
Best regards,
Anders
Original comment by cureos...@gmail.com
on 11 Aug 2014 at 9:02
@cureos.ab
>>
The project GUID:s are all different, i.e. MoreLinq and MoreLinq.Portable have
different GUID:s etc. As I mentioned in a previous code comment, I think it
makes sense to have it this way, since the .NET and PCL projects are
functionally different. (And Visual Studio does not accept it either if I keep
both projects in the same solution...)
<<
You misunderstood me there. I meant that it seems odd for the MoreLinq.Portable
project to change GUIDs between v1.x to 2.0 of the project. I wasn't expecting
MoreLinq and MoreLinq.Portable to share the same GUID.
>>
When it comes to assembly identity equivalence, I believe that the important
things are that the strong names are equivalent, i.e. that the assemblies have
the same name and are using the same .snk file.
<<
You raise a point here that makes me think of another potential issue. What if
a project uses two libs, one which is linked to MoreLinq and another to its
portable version? Since they have the same identity, you'll probably get a
conflict. I'm wondering therefore if it's a good idea at all to have the
portable version share the same assembly name!
Original comment by azizatif
on 11 Aug 2014 at 4:32
- Added labels: Milestone-Release1.1, Priority-Medium
- Removed labels: Milestone-Release1.0
Dear Aziz,
thank you for the clarification regarding the GUID:s. Now I understand what you
mean. With the new clone, this issue has been fixed; v1 and v2 projects have
the same GUID:s.
Regarding the naming: the goal should be that the portable and non-portable
assemblies share as much code as possible, right? In that case, using both
libraries in one application will inevitably lead to numerous method
duplication conflicts. I think one would want to avoid as much as possible to
use both libraries under these conditions. Given this, I don't think it is a
problem that the libraries are named the same. Rather, the fact that they share
the same strong name could be used as an advantage.
Best regards,
Anders
Original comment by cureos...@gmail.com
on 11 Aug 2014 at 4:49
@cureos.ab I don't expect an app to consciously use the portable & non-portable
version. If an app references 2 independent NuGet packages, each of which in
turn uses MoreLINQ portable & non-portable, then the app developer won't have
much chance to resolve the conflict without private builds. I'd just like to
think this through before we conclude the issue.
Original comment by azizatif
on 11 Aug 2014 at 6:57
Thanks, Aziz, I see your point. I am not sure, but for the scenario you are
outlining, I actually think it is a benefit that the portable and non-portable
packages have the same strong name. I believe (without having tested it) that
if you in such an (.NET) application explicitly reference the non-portable
assembly, the references to the PCL assembly will automatically be resolved.
But I suppose we need to run a test to verify this :-) I can give it a try if
you think it is worthwhile testing.
Best regards,
Anders
Original comment by cureos...@gmail.com
on 11 Aug 2014 at 7:35
@cureos.ab If two packages copy a dependency on MoreLinq.dll (one using
portable and the other not), you don't know which version will get
used/deployed as one may override the other. If one of the lib uses a method
not available in the portable version (e.g. Trace or ToDataTable) and the
portable version is loaded then you will get a MissingMethodException at
runtime.
Mixing identities between incompatible binaries sounds troublesome. Moreover,
if we ever want the full version to depend on the portable one as a core in the
future then one would have to split the identities anyhow. I think it might be
safest to start out with distinct identities (as you had it first). Another
option worth considering is to have one package but install the right binary
depending on the target framework.
Original comment by azizatif
on 11 Aug 2014 at 10:06
@azizatif I have now made a test as follows:
a) Create a Portable class library that references the PCL version of MoreLinq.
This library contains a method "PortableMethod" which uses the MinBy method
that is included in both the portable and non-portable versions of MoreLinq .
b) Create a .NET class library that references the non-portable version of
MoreLinq. This library contains a method "NonPortableMethod" which uses the
Trace method that is only included in the non-portable MoreLinq.
c) Create a .NET console application "ConsoleApp" that references the class
libraries in a) and b), and calls both "PortableMethod" and "NonPortableMethod".
If I explicitly reference the *portable* MoreLinq assembly in "ConsoleApp", I
*do* get a "MissingMethodException" when I run "ConsoleApp".
BUT! If I explicitly reference the non-portable MoreLinq assembly, or if do not
reference either of the MoreLinq assemblies, "ConsoleApp" executes
successfully, without throwing any exception.
It does seem that assembly resolution is capable of selecting the most specific
assembly when there are multiple assemblies with the same strong name. And in
any case, if the non-portable MoreLinq assembly is explicitly referenced, there
should not be any doubt that the referenced assembly is used throughout the
application.
However, if you still feel reluctant to use the same names for the portable and
non-portable assemblies, I am fine with that too.
Otherwise, I am all in favor of incorporating the non-portable and portable
libraries in one package. For NuGet MoreLinq users this would certainly be the
most convenient approach.
Do you want to make the final touches to the project and build files yourself?
Otherwise, I can make any updates you find necessary to my clone and you can
take it from there. Just let me know how you want me to proceed.
Best regards,
Anders
Original comment by cureos...@gmail.com
on 12 Aug 2014 at 10:02
>>
It does seem that assembly resolution is capable of selecting the most specific
assembly when there are multiple assemblies with the same strong name.
<<
I don't think this is a feature of the assembly resolution. The console app may
be incidentally working because the non-portable version in the bin overwrote
the portable version.
Original comment by azizatif
on 12 Aug 2014 at 10:28
@cureos.ab Thanks for your contribution, tests and patience with re-working the
changes.
The following merge in your clone was breaking the build:
https://code.google.com/r/cureosab-morelinq-portable/source/detail?r=49f1311c8cc
d1bea9ae148edd041cd1406e8343d
In any event, I cherry-picked your relevant changesets (so your commits are
attributed to you with the original timestamps) and have pushed them to the
main repo.
I finally decided to go with distinct identities because it is the safest
option for now that has the least chance for popping surprise.
The NuGet package is published, starting at version 1.1:
https://www.nuget.org/packages/MoreLinq.Portable/
Coinciding with that, I've also pushed morelinq version 1.1:
https://www.nuget.org/packages/morelinq/1.1.0/
Original comment by azizatif
on 12 Aug 2014 at 10:35
- Changed state: Fixed
Great, many thanks for your assistance and patience. Terrific to see that the
PCL package is already published on NuGet.
Best regards,
Anders
Original comment by cureos...@gmail.com
on 12 Aug 2014 at 10:43