Forum Xamarin.Forms

Why Shared Projects?

AdamPAdamP AUUniversity ✭✭✭✭✭

Maybe I am missing something wonderful about them but every example I see from Xamarin Forms is using a Shared Project. I have never found a solid reason to use a shared project, putting compiler directives through the code for each platform just seems like it will lead to hard to maintain code.

PCL's have been really easy and great for containing code. To me shared projects have no purpose other than really quick demo code but even still PCL's work with a little bit of DI doesn't make things particularly complex, especially with XF's inbuilt Dependency Service.

The question is, why does anyone use these project types, why does Xamarin keep building examples in them, which means all newcomers to XF start to use them? I honestly have never seen a reason in XF to use a shared project.

But I am ready to have my eyes opened in case I missed something with Shared Projects.



  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    If I remember correctly, Petzold's book suggest to use PCL

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @AlessandroCaliaro - I have asked around in other places and PCL is certainly in most people's minds the only way to go.

    I just keep seeing coding examples like the latest one:

    A shared project once again. Then I keep getting questions from newcomers and when I look at their project or source, a lot of the time its Shared Projects because the samples are what they are basing their code off.

    I think Xamarin could set a better example in these cases and I still dont know why Xamarin would code like that in the first place. I can understand there was a time before PCL's but they have been around for a long time now.

  • GeraldVersluisGeraldVersluis NLUniversity ✭✭✭✭

    The only real reason I could come up with is that you REALLY would want to use a library which is not (yet) PCL compatible. Or you are working with legacy code which provide a DLL with functionality you want to include (in fact being a library which is not PCL compatible).

    Otherwise, I as well, have not found why you would want to do a shared project these days.

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @ThomasBurkhart - Is there a particular reason you want to use compiler directives instead of just PCL's with DI?

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭
    edited January 2016

    To be honest, I'm a bit old fashioned and did not completely trust that I can do everything with DI :-) it happens that I don't need any compiler directives in my project I will change it to a PCL.

    It's my first project with Xamarin, so I thought this would be the best approach.

  • GeraldVersluisGeraldVersluis NLUniversity ✭✭✭✭

    @AdamP said:
    @ThomasBurkhart - Is there a particular reason you want to use compiler directives instead of just PCL's with DI?

    Very good question!
    In my opinion you want to stay away from compiler directives as much as possible..

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @ThomasBurkhart - Sometimes old habits die hard :)

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭

    @AdamP You are so right. I spend the last years with programming micro controllers, so all the new magic stuff like DI is hard to digest.

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭

    May ask the otehr way round, why not shared projects?

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @ThomasBurkhart - maintainability, portability and unit testing

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭

    Ok, I agree on Unit Testing, but I don't see a big advantage for the other two. In my opinion the mix of shared and PCL it's a good solution to have the advantages of both

  • AdamPAdamP AUUniversity ✭✭✭✭✭
    edited January 2016

    @ThomasBurkhart - if you agree on the unit testing then by default you agree on maintainability :)

    If something can't be easily unit tested it is normally a red flag that something is wrong with the implementation.

    If I had a shared project I would fill it with

    #if __ANDROID__ 
        // do something
       // do something else


    Then if I say, show me your Android implementation of something, you would have to search through numerous files and look for the compiler directives.

    Whereas in a PCL approach, you can go look at the native class here. It means you code that file suited towards the platform as well, rather than trying to code for numerous platforms in 1 file, where the actual implementations may be so different but you want to try and share code hence you have either a bad implementation for all 3, or 3 complete different chunks of code all doing the same thing but all in the same file.

    If there is a bug in Android only, then you would need to search the file just to find the Android parts of it that might be causing a bug.

    It becomes a nightmare as your project expands.

    And portability, how are you exactly creating something that can be easily shared among other, possibly none related projects with a Shared Project? With a PCL you create a class library and can just reference as needed. Native implementations can be stored in a native class library if needed and shared with other native projects as needed and you aren't bringing along a 2 other platforms that have nothing to do with it.

  • JohnHardmanJohnHardman GBUniversity mod

    @AdamP - The only code I have in a shared project is related to Azure services. Even that is only in the shared project because the example I was following did that. Whether it actually needs to be, I don't know. My app is pretty big, interacts with all sorts of bits on the device, and nothing else has needed to be in a shared project.

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭

    @AdamP Very good arguments. As soon as I have it a bit more working I will try to refactor it.

  • AdamPAdamP AUUniversity ✭✭✭✭✭
    edited January 2016

    @AlessandroCaliaro - I went on a blogging rant yesterday as well :)

    I already knew @TheRealJasonSmith didn't like SharedProjects, which also leads me to the question why do the Xamarin Staff keep creating Xamarin Examples using them. I was honestly wondering what the appeal was because I never saw it.

  • DavidDancyDavidDancy AUMember ✭✭✭✭

    The only reason I find Shared Projects at all attractive is that PCLs don't support file system operations. It seems utterly bizarre to me that we have networking support in PCLs (HttpClient et al) but nothing for the file system.

    The only time I've ever even used a Shared Project was when I made a Couchbase demo - but that was also only because Couchbase Mobile didn't (and to my knowledge still doesn't) have a PCL implementation. Also inconvenient, but their priorities seem to be in other directions.

    Otherwise (and accepting the fact that operating with files is going to require DI + some work) it's PCL all the time for me.

  • I've used Shared Projects a bunch (probably too much I admit) but at no point did it ever cross my mind to use compiler directives in them because, well, yuck. The reason I used Shared Projects was pretty much along the lines of what DavidDancy said - not everything is supported in PCLs and early on it was a pain getting some things to work. It's much better now though and I'm using PCLs more and more.

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @DuncanCole.3599 - Thats were DI comes into it. But was DI difficult to use in some way or just because you are new to it all or was there something specific? (sorry don't know how long you have been programming).

  • I was using DI extensively for all platform specific code but for certain functions like for example file system logic it wasn't required and it would be if I were using a PCL. It's quite possible I've overlooked something obvious in my approach though. :) If so, I'm sure I'll find out soon as I'm about to refactor an old Shared Project that has some file system logic in it.

    (Additionally, I never had in trouble unit testing my Shared Project code. Although, now that VS 2015( I think?) doesn't let Unit Test projects reference Shared Projects it requires another intermediary project which is awful and part of the reason I'm looking into PCLs again)

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭

    @DavidDancy You can have FileAccess in PCL by using PCLStorage component works great.

    Btw. Just implemented my first DependyService and it didn't hurt ;-) Sometimes it's hard for Dinosours like me to get used to these modern stuff.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Ok guys, the Commander in chief lights the way

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    @TheRealJasonSmith vs @MigueldeIcaza who will win? I accept bets

  • BrianRepettiBrianRepetti USUniversity ✭✭✭

    I found Pickles help to produce re-usable code. Especially when you are working on multiple apps.

    If you have a very small / single app then shared project will probably be fine for you and take some complexity away.

  • MigueldeIcazaMigueldeIcaza USXamarin Team Xamurai

    There is no one-size fits all; I tried to capture some of my thoughts on when to use each on the post, but they are really two different tools.

    If I am not building a framework, and just an app, I like shared code a lot more. A big component will be a style and requirements for a particular project.

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    Maybe this is where I am not seeing it, I never develop a small simple app, or something that ever stays a small simple app.

    Hence still not seeing any benefit of simplicity over a PCL. It is a similar amount of work either way from my experience. Shared Projects just seem like a project style that eventually runs into limitations.

    About the #ifdef they come even in the default Windows Shared Projects so they occur naturally straight out of the box and as soon as they do, it is something hidden away in class files changing functionality per project.

    I do agree the partial class approach works really well for Shared Projects and if they do choose Shared Projects then it is the way to go over #ifdef without question.

    With the limited API's mentioned as a disadvantage, I see it as an awesome advantage. I want those API's limited unless explicitly implemented otherwise you start using things you weren't meant to, or just add more surface area on API's you use. Even in a single developer project, limiting those API's makes you think.

    Developers will sometimes reinvent the wheel on a rather than use a pre-existing implementation (as a broader NuGet package or something already developed specifically for that project) that has been tested against more use cases than they will generally think of. It causes you to think of what you are actually going to use in that project, rather than lets just quickly code this in.

  • HunumanHunuman GBMember ✭✭✭✭

    @AdamP - Your point about people reinventing the wheel is spot on.
    This is driven in part by fear of change and the comfort of the familiar IMO.

    I find it worrying the number of developers I meet who are afraid of learning new languages/frameworks/approaches.
    Sadly many of them don't even seem to have any faith in their own ability to learn.

    In previous projects, where I'd been called in to help recover a failing project, new tools/frameworks had been selected.
    On more than one occasion I found the customer's development staff had wasted months reinventing the paradigms of their old tools and frameworks, within the new, instead of actually proceeding with the project.

    Technologists who are afraid of new technology, who'd a thunk it?

    As regards PCL's vs Shared, I do use both but prefer the PCL approach, which sits better with my old OO roots.


  • AdamPAdamP AUUniversity ✭✭✭✭✭

    Thanks to everyone who has joined in this discussion. I enjoy putting these thoughts to the test.

  • TheRealJasonSmithTheRealJasonSmith USXamarin Team Xamurai

    +1 great thread

  • voidvoid DKBeta ✭✭✭

    I started using project linking waay back.

    Then I moved on to shared projects. And I like shared projects for applications. I don't really have that many compiler directives.

    I've begun moving tried, tested and applicable code into PCLs so that I can reuse this code among applications.

    I will be using a mix of shared/PCL in the foreseeable future.

  • rogiheerogihee NLMember ✭✭✭

    I stand firmly on the side of @MigueldeIcaza : I use both approaches. I use Shared Projects for my app (I don't use XAML so no need for PCL) and for a shared components lib with custom controls I use in all my projects. In the platform specifics libs I added a few classes to handle logging on Android and such. Other shared libs I made are PCL's because I also share them with WPF/WinForms projects on the desktop.

    I have never (had to) use ifdefs and I found Shared Projects a lot more powerful and simpler to deal with than PCL's, which in my view have rather more limitations than Shared Projects. PCL's are a complex system solving a problem I don't have, I just want to write a simple app!

    Yes, there are great libraries nowadays for all that logging/settings/networking, but they are all using dependency injection and I consider that an anti-pattern in most cases (to stir up some conversation ;-), whenever there is a problem in my code I want to be able to trace it step by step and not jump all over the place and see what part made a particular call to a method. Simplicity rules.

    I also tend to limit the amount of external libraries I use to the absolute minimum, and that is not about re-inventing the wheel but stability concerns. I have had more than one occasion where an upgrade of an open source well used library had a regression which broke my app.

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    Great points @RogiervanderHee. I see simplicity in a slightly different light, rather than jumping around through PCLs, they should have a defined contract and perform as expected, if it doesn't its easy to pick up the component that is causing the issue and its isolated. Unit tests on the API contract should isolate the method causing the issue.

    Stability concerns I can relate to, XF has had its fair share of regressions but I don't see how that limits upgrading. If a package causes a regression, I just report the bug, revert to the previous version and stick on that until resolved. The benefits of performance enhancements and free bugs fixes from packages, more features and not to mention the huge testing done by its user base normally means it will be done better than I could implement within my time frames.

    Upgrading a package isn't mandatory and if you wrote your own it wouldn't be upgrading anyway.

    I agree that Service Locator is certainly an anti-pattern but constructor injection resolves that. The global IoC however can certainly be debated.

    I always use XAML for views. I see XAML as a language built for views. HTML, CSS, XAML and other languages are built for the purpose of visuals. C# is built for processing data, business logic etc. But that is another discussion altogether.

    The disparity in views certainly seems to come down to project, programming style and sole developer to larger teams. I still haven't changed my stance on PCL's over Shared Projects but at least have a greater understanding of where others are coming from.

    It might all come down to the level of control a developer wishes to exert over their project. PCL's demand high levels of control and uses abstraction to enforce that control. Shared Projects allow a more free flowing development style.

    Interesting food for thought anyway.

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    I was thinking maybe I had been too harsh on Shared Projects and they might have their merits in certain use cases. Then I came across this:

    Is this really the recommended way to implement SQLite on a SharedProject? Because it uses a lot of ifdefs and you have to copy and paste code rather than using a NuGet package.

    Or is there be a better way to implement that with SharedProjects? (I am genuinely asking out of curiosity)

    That current example stands as some of the main reasons I would never use a SharedProject.

  • BrianRepettiBrianRepetti USUniversity ✭✭✭

    Just wanted to "share"... I ran into a case where I had to use a shared project. I have a project that needs to use existing code that dates back to Windows Mobile. Some of the inherited classes used were not available in PCL. So instead of rewriting code we just used shared projects. We have plans to migrate the code into a PCL eventually but the shared project was able to get it done for now. It works better than file linking in the native projects.

  • SanderESanderE USMember ✭✭
    edited June 2016

    @AdamP said:
    I was thinking maybe I had been too harsh on Shared Projects and they might have their merits in certain use cases. Then I came across this:

    Is this really the recommended way to implement SQLite on a SharedProject? Because it uses a lot of ifdefs and you have to copy and paste code rather than using a NuGet package.

    Or is there be a better way to implement that with SharedProjects? (I am genuinely asking out of curiosity)

    That current example stands as some of the main reasons I would never use a SharedProject.

    Of course that isn't the way to properly implement that with a Shared Project. You'd do it the exact same way as with a PCL, namely by creating an interface in the shared code, implementing these per platform and then injecting it in the shared code.

    And that's basically why I always go for Shared Projects for actual apps - You can and should develop the exact same way with a shared project as you would in a PCL. The only difference is you theoretically have some more options if you really, really need it.

    To me, projects are units of deployment. A PCL is great if you need to distribute the assembly (aka deploy it) somewhere outside of your app. But the shared code of your app? It exists solely to function in your platform assembly, and thus the bonus of a PCL (distribute one assembly for multiple platforms) is gone because you only work with said code and you never deploy it as a stand-alone assembly. You build it, then add it to the platforms you are actually distributing.

    Am I building cross-platform functionality that DOES need to be distributed outside of an app? That means I am building a library for more than one app, and it needs to be a PCL.
    Am I building shared code for an application that's never going to be distributed on its own? Shared Project, with proper coding guidelines and all that jazz.

    Just because you CAN make shitty code in a shared project doesn't mean you should. And I guess that's a last reason to not pick Shared Projects, if your dev team is large and you don't trust them to all write proper code, you somewhat enforce a few things in PCLs.

  • PhilipOGormanPhilipOGorman USMember ✭✭✭

    I've been using PCL from the start (1.5+ years), I really like it, I use DI for any native specific stuff. I use exclusively xaml and MVVM. Now I am looking into using this library:

    Their nugets only allow for development using the Shared Project set up.
    This might be a stupid question - but can I still use only XAML and no code behind when using Shared?

  • PhilipOGormanPhilipOGorman USMember ✭✭✭

    @PhilipOGorman said:
    I've been using PCL from the start (1.5+ years), I really like it, I use DI for any native specific stuff. I use exclusively xaml and MVVM. Now I am looking into using this library:

    Their nugets only allow for development using the Shared Project set up.
    This might be a stupid question - but can I still use only XAML and no code behind when using Shared?

    OK - It was a stupid question. I was able to delete my pcl project, create a new shared one, and reuse all the old PCL code.
    The names spaces all had to be updated.
    Initially I had to delete all of the xaml files as I was getting an InitializeComponent error. I have to manually add them back and copy and paste the old code back in.

    So - from what I can see, I can still use all the same patterns as before - DI + MVVM and xaml - but I'm not forced to. Also I'm not sure how I will unit test viewmodels.

  • ThomasBurkhartThomasBurkhart DEMember ✭✭✭✭

    @PhilipOGorman I'M sure readding was not necessary. MOt of this sort of errors come because properties of existing Xaml pages added to new projects are set wrong.

Sign In or Register to comment.