94

... We are forced to stay on the lowest API level of the framework (.NET Standard) … This to me highlights the fact that, not only are you potentially restricting yourselves too much, you may also be heading for a nasty fall with your approach. .NET Standard is not, and never will be "the lowest API level of the framework". The most restrictive set of APIs ...


74

Use dependency injection, but whenever your constructor argument lists become too big, refactor it using a Facade Service. The idea is to group some of the constructor arguments together, introducing a new abstraction. For example, you could introduce a new type SessionEnvironment encapsulating a DBSessionProvider, the UserSession and the loaded ...


51

We are forced to stay on the lowest API level of the framework (.net standard). The reasoning behind this is that a new platform could one day arrive that only supports that very low API level. The reasoning here is rather backwards. Older, lower API levels are more likely to become obsolete and unsupported than newer ones. While I agree that staying a ...


33

You should generally upgrade dependencies when: It's required There's an advantage to do so Not doing so is disadvantageous (These are not mutually exclusive.) Motivation 1 ("when you have to") is the most urgent driver. Some component or platform on which you depend (e.g. Heroku) demands it, and you have to fall in line. Required upgrades often cascade ...


25

It maintains referential integrity (yes but can be maintained without it too) You are technically correct that if you're able to maintain referential integrity yourself, you don't need the constraint to exist. But by that same logic, you don't need fire insurance as long as your house doesn't burn down, and you don't need health insurance as long as you ...


21

For .NET it may depend on the deployment target. .NET 3.5 is supported in even early editions of Windows XP, whereas 4.5 is only supported on Vista and above. At my workplace we opted to stay on 4.0 because we still have workstations running on Windows XP Pro SP3 (which 4.0 supports). We cannot consider migrating until next year or so just because of that. ...


20

Refactor Slowly. Expect this to take some time to complete, and may occur over several iterations before you can completely remove your Utils assembly. Overall Approach: First take some time and think of how you want these utility assemblies to look when you're done. Don't worry too much about your existing code, think of the end goal. For example, you ...


19

Dependecy injection massively swells constructor argument lists and it smears some aspects all over your code. From that, it doesn't seem like you understand DI proper - the idea is to invert the object instantiation pattern inside of a factory. Your specific problem seems to be a more general OOP problem. Why can't the objects just throw normal, non-...


19

This is one of the reasons you're using open-source software, right? You could make the very same argument for "what happens if my very expensive, proprietary, closed-source library suddenly falls over? Will there be someone available at [large, monolithic software company] to fix it for me?" With open-source software, at least you have the chance to ...


15

create a one extra project in which all common things are defined This is the exactly first step to share reusable parts - and its the easy part. The more challenging part is to decide if the two projects which are using the shared library shall have independent release cycles (or not), and if it should be possible that "project A" uses version 1.0 of your ...


14

I'd personally go for many small libraries. Discourages developers from creating dependencies between otherwise unrelated packages. Smaller more manageable libraries that are much more focused. Easier to break up and have separate teams manage each library. Once you have a new requirement that's sufficiently complex, its better to add a new module rather ...


14

"Good enough is the enemy of better." -- Jerry Pournelle Seriously, there has to be a reason for an upgrade besides just "ooh, shiny!". Among other issues, any time you switch versions of a package your code depends on, you switch out one set of bugs that you're adapted for to another set that you may not be. In the process of switching, you frequently ...


14

I am comfortable to say that an object belonging to a layer can depend on objects from lower layers To be honest, I don't think you should be comfortable with that. When dealing with anything but a trivial system, I'd aim to ensure all layers only ever depend on abstractions from other layers; both lower and higher. So for example, Obj 1 should not depend ...


13

Your solution is the right one. Put the shared code into a another project that builds its own JAR file, and use it in both projects. When building the JAR file, you may want to include the version in the name, e.g. in Debian style; libmyproject-shared-1.0.jar It doesn't prevent versioning trouble, but it should help. I've never used Maven, but I ...


12

The confusion you are having here is because you are trying to write a test about the implementation details, not about the desired effect. Thinking instead about the desired behaviors of the class is likely to lead you to a better test. In this example, it seems to me you have two behaviors you want to test: When added an effect does something to the ...


12

You have already listed the disadvantages of the static factory pattern quite well, but I don't quite agree with the disadvantages of the dependency injection pattern: That dependency injection requires you to write code for each dependency is a not a bug, but a feature: It forces you to think about whether you really need these dependencies, thereby ...


12

The question you ask is generalized, but the issue here is not what you think it is. The majority of this answer focuses on the real issue, but I want to respond to your direct question first. So my question is, should I move the codes in validateFormat() into submit(), in order to fit YAGNI rule? Unless your validation logic is complex enough to warrant ...


11

Libraries are great and certainly solve a lot of problems very quickly. However they never solve every problem and even gluing together many libraries isn't enough to solve many specific use cases. Programmers are not typists. We've had that discussion before. Despite all the libraries, frameworks and out of the box solutions, there is always something your ...


11

The solution to developing applications where bugs or lack of features have a high risk of causing your work to stop is to not use high risk libraries. Boring and lame, I know.. You said this is an alpha release. Don't use alpha releases for critical projects. It's not even a beta release, let alone 1.0 so this sort of thing is to be expected. The entire ...


11

On the whole these things are good for your customers. Even a popular open source library might be impossible for them to use for some reason. For example, they may have signed a contract with their customers promising not to use open source products. However, as you point out, these features are not without cost. Time to market Size of package ...


10

Is it better to expose or hide dependency in OOP? It's best to do both. Before I explain that let me explore the problems with your proposals. Let's say I have an object A, which is too big(having too many methods and variables). So, I break it down to smaller objects. This is good. Always break objects down until they have only one responsibility, ...


10

It's not your problem. It is up to your end user to resolve. It just comes with the territory of using third-party dependencies, and I've had to resolve dependency conflicts more times than I count. You can't expect to accommodate every project's specific dependency conflicts. Your software should operate correctly with the latest versions of your ...


10

I have always avoided this problem by using Nuget. If you are developing .net its the 'standard' out of the box package manager and works very well. The downside, if any, is that your dependencies are now binary dlls rather than source code, which you can debug and edit as you go. This imposes some restrictions on your day to day working practices, you ...


10

Yes, objects in one layer can have direct dependencies among each other, sometimes even cyclic ones - that is actually what makes the core difference to the allowed dependencies between objects in different layers, where either no direct dependencies are allowed, or just a strict dependency direction . However, that does not mean they should have such ...


9

The codependency module may be what you're looking for, or anything that does something similar to: declare optional dependencies in package.json that aren't automatically installed by npm install, say optionalPeerDependencies a custom require-style function that knows about optionalPeerDependencies and does the right thing, including throwing/warning when ...


9

If you want simple optional dependencies like plugins, e.g. if you install foo you will run it colorful but if not installed, you don't have any problem and see it in gray, then you could use optionalDependecies in the package.json: { "name": "watchit", "version": "1.2.3", "optionalDependencies": { "foo": "^2.0.0" } } And in the code: try { ...


9

Should I pass the Graphics to the Draw() function? Well, when I saw this design, first thing which came into my mind was "why the heck does the TextBlock have a Graphics attribute at all? Should it not be possible to draw the same block on two different graphics contexts? Should the TextBlock object not have a lifetime which may be longer than the lifetime ...


9

Git submodules are broken: workflow is hard to follow history is cluttered unintuitive behaviour for non-git-experts easily broken (see section "Submodules break easily, and submodules break badly" in the link above) We have been using them for something similar as you describe, and it is hell now. You modify a piece of code, and you're not sure whether it ...


9

@17of26 gave a lot of good reasons why #2 is dangerous, and why #1 makes more sense. But I think there is one thing missing, for which I recommend the following: download the code of the library you will use, add it to the project folder, but don't modify it arbitrarily!! Avoid modifications if possible. If that is not possible, try to keep the direct ...


8

The semantic versioning rules are applied to your software from the perspective of your users. If your API has changed and is not backwards-compatible, you should update your major version number. It sounds like this isn't the case, though. It sounds like your API hasn't changed - clients who were using your previous version can simply drop in the new ...


Only top voted, non community-wiki answers of a minimum length are eligible