9

As our devs are writing internal applications, often times we need to share code. There are various ways to do this, but it usually comes down to creating a nuget package on a shared server or hosting a web api internally. We don't have a definitive way to decide between the 2 and currently have a mixture of both. Any suggestions/guidance of when to do one over the other?

To get a little more specific... Say I have a few general use methods to FormatXXX(), CalculateXXX(), SendXXX(), etc... that many apps could benefit from. Should this be an internal web api, or a nuget package?

We are a .Net shop, and use VS 2017, TFS (with git). We mostly build web apps, web api's, wcf services, and command line apps. We interface with 3rd party api's all the time.

goku_da_master
  • 201
  • 2
  • 6
  • 4
    `but it usually comes down to creating a nuget package on a shared server or hosting a web api internally` -- Why are these the two choices? They represent orthogonal concerns. – Robert Harvey Jan 18 '18 at 19:53
  • Not sure what you're getting at... I'm looking for the recommended approach. I know both solutions work, but what's preferred when? I was in a discussion with some collegues about whether to expose certain functionality in an API or create a library with a nuget. It was a while ago and can't remember exactly what this functionality was. – goku_da_master Jan 18 '18 at 20:08
  • What about simply providing a shared library or project? Why bother with NuGet or a web API? – Robert Harvey Jan 18 '18 at 20:11
  • If it's just a dll/library you're trying to share between solutions without nuget then how would you share it across multiple solutions/apps? Our solutions are all in version control and you don't commit dll's. – goku_da_master Jan 18 '18 at 20:15
  • By using a shared project. See https://git-scm.com/book/en/v2/Git-Tools-Submodules – Robert Harvey Jan 18 '18 at 20:17
  • I didn't know about git submodules. Sounds a lot like subversion externals. Good to know. – goku_da_master Jan 18 '18 at 20:40

4 Answers4

4

If its a pure function then you want the code to execute on the same CPU as the app. a nuget package is a good way of getting that code into your project.

If the function has side effects that you want to be global. ie every time this function runs we MUST generate an audit log. or, This function must only have a single instance running at a time and stop when we reach 1000 calls per day! Or more commonly, this function accesses a common database and we need to stop people deleting it. Then you need to control the way the function is used and must host it yourself. Only exposing an API for consumers to call.

The down side of a hosted API is that you have to host the server, probably a in a fail-over cluster so there is a cost involved. Plus sending the call over the network is slow.

A note on shared code solutions:

It's been suggested that you use shared code instead of NuGet packages for internal projects.

While this is a solution the downside over nuget is that each application that uses the code will build its own version of the package. So you lose the benefits of versioning, signing, multiple platform builds etc that you can get from nuget or other package managers.

I would suggest its best to treat you internal 'customers' the same as external ones and let them pull all the packages, internal and external from nuget.

Ewan
  • 70,664
  • 5
  • 76
  • 161
  • Worth noting: you can't step through the code of a NuGet package; it has to be a resident project in the solution to get that capability. Your description of "shared code" is not the same as my description of a "shared project." A shared project is a single source of truth. – Robert Harvey Jan 19 '18 at 16:13
  • well... you can include the pdb – Ewan Jan 19 '18 at 16:14
  • 1
    Which will tell you what line of code threw the exception, but will not provide any additional debugging facilities. – Robert Harvey Jan 19 '18 at 16:25
  • this is .net we are talking, so the dll is pretty much full code. vs will auto decompile it with the right plugins. But yes, its not the same. – Ewan Jan 19 '18 at 16:29
  • Sure. But at that point you're piling software on top of software to solve problems that don't exist with shared projects. That was the choice we faced: full CI (which we didn't really need at the time) to fully support NuGet packages that we didn't really want. – Robert Harvey Jan 19 '18 at 16:47
  • You have different problems with shared code. Nuget is forcing you to publish your library. You consume it with the same level of expectation that you do with an external library. ie that you wont have to debug it – Ewan Jan 19 '18 at 17:05
  • Of course. Whether you need that level of rigor in a shared library is a matter of taste, I suppose. The degree of robustness in a library that you make available to the public is different than in code that you just want to share internally. – Robert Harvey Jan 19 '18 at 17:39
  • 1
    A matter of head/project count I think. at some point you dont want to see the code anymore – Ewan Jan 19 '18 at 17:46
3

Use NuGet when your project, library or framework needs to be publicly distributed to software developers outside of your organization. *

Use a web API when you need the benefits that a web API provides. Generally, that means you have multiple software front-ends that need to communicate with server functionality of some sort.

In all other cases, put the shared project into source control and allow your developers to include it in their own solutions.

*If you have a robust Continuous Integration program, you can try creating NuGet packages and using those internally. We did this for awhile with decidedly mixed results. Getting things to build properly was a constant problem. You need CI to do it correctly with NuGet, in my opinion.

Further Reading
Git Submodules

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • 4
    its pretty common to use nuget to share internal libraries these days – Ewan Jan 18 '18 at 20:20
  • 2
    @ewan: We tried that at our last job, and it was a minor nightmare. It's overkill for local sharing. – Robert Harvey Jan 18 '18 at 20:20
  • hmm arguable, but its still a common practice. eg. I have an api and I want share the client, or data models or a logging framework etc. better than many of the alternatives – Ewan Jan 18 '18 at 20:23
  • 1
    @Ewan. Maybe if you have full CI stood up. We didn't. Read the Git Submodules article I linked. – Robert Harvey Jan 18 '18 at 20:23
  • I have had similar bad experiences, but with shared source solutions. Would always choose nuget personally. But yeah, you do have to pay the CI taxes – Ewan Jan 18 '18 at 20:25
  • Another + for git submodules is the ability to debug into the code. However, after following your link, adding and using submodules isn't as easy as creating a nuget package. Most of our team uses tfs from within VS so command line git is unnecessary. Anyway, the submodules documentation says it's more common to use submodules if you want to edit the submodule, not just use it. – goku_da_master Jan 18 '18 at 20:57
  • We use Nuget packages to share the client libraries for our internal webapis. So all the things is also an option – Nathan Cooper Jan 19 '18 at 00:25
  • @NathanCooper: I can see doing that in a *big* shop. For smaller teams, the added complexity isn't worth the trouble. – Robert Harvey Jan 19 '18 at 15:47
  • @RobertHarvey yeah. It's actually a terrible idea to make all you architectural decision on day 1. Obviously you start out simple and split later on – Nathan Cooper Jan 19 '18 at 16:01
1

Favor a service if you need full control of execution or some centralized resources (databases, mail servers, etc.). Favor sharing your source when resources aren't shared, when ultra low latency is necessary, or when your ability to promise uptime / provide support is limited.

Either way, I would personally not use a NuGet package to share code internally. I'd share my repo and toss a DLL on a wiki (or shared drive or whatever) -- for consumers who don't want to continually recompile my code.

svidgen
  • 13,414
  • 2
  • 34
  • 60
0

I came here because I have this very question. We've made a lot of our common code nuget packages and the number of packages are increasing as are the versions. I don't want to have to update a dozen projects when new versions release so I was already leaning towards moving things to an API (all of our code is for internal use).

Another benefit of choosing an API over a nuget package is you don't force an implementation requirement to use the code. This means if you want to change the View layer of your apps from one framework or technology to another, you can. That's what clinches it for me because we're sort of at the start of migrating projects from one framework to another.

jason
  • 101
  • 1