EDIT : got it shorter.
We created three modules following the prism doc and our requirements.
We did a horizontal slices with modules.
SharedServices
BusinessLogic
UserInterface
In the UserInterface we are using Syncfusion components and other packages, and It would be great to put everything in the UserInterface module but how can we reference nuget assemblies from that module in the shell (to apply theming for example) to avoid having references in each modules & the shell ?
Should we add nugetpackage to each module and the shell (is it bad... ?) or is it possible to have one module which defines base class referencing external assemblies for example and that would be themable (with ResourceDictionary) & usable in the whole solution (shell & other modules) .
Thanks.
Very broad question, it might well be closed, but I try to give you a few guiding thoughts:
Generally, you either slice horizontally (as you did, UI-module with all the views plus logic-module with all the services) or vertically (as your Product-module suggests: views, view models, services for the product in one module, those for the user in another).
You can do both, but then you should "slice through", so one module for product-ui, one for user-ui, one for product-services, one for user-services... you get the idea. That means a lot of modules, though.
Also, when creating your modules, have an idea of what you want to achieve. Modules can encapsulate components to be reused in another app. Or they can encapsulate exchangeable components, so you could create a car-sharing app today and tomorrow swap out the car-module for a bike-module and have a bike-sharing app. Or they can be used to enforce segregation of code based on risk analysis in a regulated environment. What I'm trying to convey: don't create modules just to have modules, make each module have a defined purpose.
Also, define the interfaces for the modules. I don't like modules to reference each other, as it effectively destroys all segregation that would otherwise be there. Create seperate non-module assemblies that only contain public interfaces. Then make your modules contain the implementations as internal types. In an ideal world, no module assembly contains a public type. The interface-assemblies can be either per module or per consumer or per link between modules (those checked boxes in your N2-chart, you have one, don't you?).
You want to keep the number of modules reasonable, as well as the dependencies between them (not as in "assembly references" but through interface-assembly).
how can we reference nuget assemblies from that module in the shell (to apply theming for example) to avoid having references in each modules & the shell ?
You should separate the "interface" part (e.g. base classes or DTOs, not part of the module) and the actual services part (that's the module). Example: unity has a nuget package for the interfaces (Unity.Abstractions) and one that contains the container implementation (Unity.Container). There's nothing wrong with everyone referencing the interface, basically, that's saying "I want to use that interface".
I have a question related to V4L-DVB drivers. Following the
Building/Compiling the Latest V4L-DVB Source Code link, there are 3 ways to
compile. I am curious about the last approach (More "Manually
Intensive" Approach). It allows me to choose the components that I
wish to build and install using the "make menuconfig". Some of these components (i.e. "CONFIG_MEDIA_ATTACH") are used in pre-processor directives that define a function in one shape if defined, and a function in another if not defined (i.e.
dvb_attach, dvb_detach) in the resulting modules (i.e. dvb_core.ko)
that will be loaded by most of the DVB drivers. What happens if there are two
drivers (*.ko modules) on the same host machine, one that needs dvb_core.ko with
CONFIG_MEDIA_ATTACH defined and another that needs dvb_core.ko with
CONFIG_MEDIA_ATTACH undefined, is there a clean way to handle this?
What is also not clear to me is: Since the V4L compilation environment seems very customizable (by setting the .config file), if I develop a driver using V4L-DVB structures, there is a big chance that it has conflicts with other drivers since each driver has its own custom settings. Is my understanding correct?
Thanks!
Dave
In SugarCRM, you can create your custom modules (e.g. MyModule) and they are kept in /modules just like stock objects, with any default metadata, views, language files, etc. For a custom module MyModule, you might have something like:
/modules/MyModule/MyModule.class.php
/modules/MyModule/MyModule.php
/modules/MyModule/language/
/modules/MyModule/metadata
And so on, so that everything is nicely defined and all the modules are kept together. The module becomes registered with the system by a file such as /custom/Extension/application/Include/MyModule.php with contents something like:
<?php
$beanList['MyModule'] = 'MyModule';
$beanFiles['MyModule'] = 'modules/MyModule/MyModule.php';
$moduleList[] = 'MyModule';
Obviously, the $beanFiles array references where we can find the base module's class, usually an extension of the SugarBean object. Recently I was advised that we can adjust that file's location for the sake of customization, and it makes sense to a degree. Setting it like $beanFiles['MyModule'] = 'custom/modules/MyModule/MyModule.php'; would allow us to access the base class via Module Loader even if the security scan tool prevents core file changes, and this would also allow us to not exactly extend, but replace stock modules like Accounts or Calls, without modifying core files and having system upgrades to wipe out the changes.
So here's my question: what is the best practice here? I've been working with SugarCRM pretty intensely for several years and this is the first time I've ever been tempted to modify the $beanFiles array. My concern is that I'm deviating from best practice here, and also that somehow both files modules/MyModule/MyModule.php and custom/modules/MyModule/MyModule.php could be loaded which would cause a class name conflict in PHP (i.e. because both classes are named MyModule...). Obviously, any references to the class would need to be updated (e.g. an entryPoint that works with this module), but am I missing any potential ramifications?
Technically it should be fine, but I can see how it could be possible that both the core version and your version could conflict if both are referenced. It all depends on the scenario, but I prefer to extend the core bean and find somewhere in the stack where I can have my custom version used in place of the core bean. I wrote up an example a couple of years ago here: https://www.sugaroutfitters.com/blog/safely-customizing-a-core-bean-in-sugarcrm
For most use-cases, there's a way to hijack Sugar to use your bean at a given point.
If you can't get around it you can always grep to see where the core module is explicitly being included to ensure that there won't be conflict down the road.
I have a legacy java project that we have been moving to buildr/artifactory from ant/jars in svn.
The primary code is in the default (src/main/java) folder, but we have a few external source paths, for various tests that we can't move into the default folder, but we want to have access with it.
Currently, when adding a new library/regenerating IDE fields, it does not pick up these source paths, and I can't find a succinct discussion in the buildr manual for how to actually add them, rather than re-adding everything manually in eclipse (which just gets wiped out on the next regen).
Any idea how to have multiple source paths get picked up explicitly by buildr so that the idea/eclipse targets generate properly?
There are two ways that I know will work with IDEA. The second one might also work with Eclipse, while the first is specific to the idea task.
The IDEA-specific solution:
define 'proj' do
# ...
iml.main_source_directories << _('src/other')
end
iml also has test_source_directories and excluded_directories arrays you can append to.
The possibly eclipse-compatible solution, with more background than you probably want:
The iml object gets its default values for the main and test source directory arrays from project.compile.sources and project.test.compile.sources (slight simplification; resources are considered also). Buildr defines these .sources project attributes from the layout, so instead of explicitly appending to the iml attributes, you could use a custom layout for your project that includes your special source paths. That might work with the eclipse task, but I haven't tried it.
Problem
Your organization has many separate applications, some of which interact with each other (to form "systems"). You need to deploy these applications to separate environments to facilitate staged testing (for example, DEV, QA, UAT, PROD). A given application needs to be configured slightly differently in each environment (each environment has a separate database, for example). You want this re-configuration to be handled by some sort of automated mechanism so that your release managers don't have to manually configure each application every time it is deployed to a different environment.
Desired Features
I would like to design an organization-wide configuration solution with the following properties (ideally):
Supports "one click" deployments (only the environment needs to be specified, and no manual re-configuration during/after deployment should be necessary).
There should be a single "system of record" where a shared environment-dependent property is specified (such as a database connection string that is shared by many applications).
Supports re-configuration of deployed applications (in the event that an environment-specific property needs to change), ideally without requiring a re-deployment of the application.
Allows an application to be run on the same machine, but in different environments (run a PROD instance and a DEV instance simultaneously).
Possible Solutions
I see two basic directions in which a solution could go:
Make all applications "environment aware". You would pass the environment name (DEV, QA, etc) at the command line to the app, and then the app is "smart" enough to figure out the environment-specific configuration values at run-time. The app could fetch the values from flat files deployed along with the app, or from a central configuration service.
Applications are not "smart" as they are in #1, and simply fetch configuration by property name from config files deployed with the app. The values of these properties are injected into the config files at deploy-time by the install program/script. That install script takes the environment name and fetches all relevant configuration values from a central configuration service.
Question
How would/have you achieved a configuration solution that solves these problems and supports these desired features? Am I on target with the two possible solutions? Do you have a preference between those solutions? Also, please feel free to tell me that I'm thinking about the problem all wrong. Any feedback would be greatly appreciated.
We've all run into these kinds of things, particularly in large organizations. I think it's most important to manage your own expectations first, and also ask whether it's really necessary to tell every system and subsystem on a given box to "change to DEV mode" or "change to PROD mode". My personal recommendation is as follows:
Make individual boxes responsible for a different stage - i.e. "this is a DEV box", and "this is a PROD box".
Collect as much of the configuration that differs from box to box in one location, even if it requires soft links or scripts that collect the information to then print out.
A. This way, you can easily "dump this box's configuration" in two places and see what differs, for example after a new deployment.
B. You can also make configuration changes separate from software changes, at least to some degree, which is a good way to root out bugs that happen at release time.
Then have everything base its configuration on something/somewhere that is not baked-in or hard-coded - just make sure to collect and document it in that one location. It almost doesn't matter what the mechanism is, which is a good thing, because some systems just don't want to be forced to use some mechanisms or others.
Sorry if this is too general an answer - the question was very general. I've worked in several large software-based organizations before, and this seemed to be the best approach. Using a standalone server as "one unit of deployment" is the most realistic scenario (though sometimes its expensive), since applications affect each other, and no matter how careful you are, you destabilize a whole system when you move any given gear or cog.
The alternative gets very complex very quickly. You need to start rewriting the applications that you have control over in order to have them accept a "DEV" switch, and you end up adding layers of kludge to the ones you don't have control over. Usually, the ones you don't have control over at least base their properties on something defined on a system-wide level, unless they are "calling the mothership for instructions".
It's easier to redirect people to a remote location and have them "use DEV" vs "use PROD" than it is to "make this machine run like DEV" vs "make this machine run like PROD". And if you're mixing things up, like having a DEV task run together on the same box as a PROD task, then that's not a realistic scenario anyways: I guarantee that eventually you will be granting illegal DEV-only access to somebody on PROD, and you'll have a DEV task wipe out a PROD database.
Hope this helps. Let me know if you'd like to discuss more specifics involved.
I personally prefer solution 2 (the app should know itself, by its configuration, what environment it is running in). With solution 1 (pass the environment name as a startup parameter) the danger of using the wrong environment specifier is much too high. Accessing the TEST database from PROD code and vice versa may cause mayhem, if the two installed code bases are not of the same version, as is often the case.
My current project uses solution 1, but I don't like that. A previous project I worked on used a variation of solution 2: The build process generated one setup file for every environment, making sure that they contained the same code base but appropriate configuration paramters. That worked like a charm, but I know it contradicts the paradigm that the "exact same build files must be deployed everywhere".
I think I have asked a related, self-answered, question, before I read this one : How to organize code so that we can move and update it without having to edit the location of the configuration file? . So, on that basis, I provide an answer here. I don't like the idea of "smart" application (solution 1 here) for such a simple task as finding environment settings. It seems a complicated framework for something that should be simple. The idea of an install script (solution 2 here) is powerful, but it is useful to allow the user to change the content of the config file, but would it allow to change the location of this config file? What is this "central configuration service", where is it located? My answer is that I would go with option 2, if the goal is to set the content of the configuration file, but I feel that the issue of the location of this configuration file remains unanswered here.
If you're using JSON to store/transmit configuration (or can use JSON in your pre-deploy process to output to some other format) you can annotate key/property names for environment/context-specific values with arbitrary or environment-specific suffixes, and then dynamically prefer/discriminate them at build/deploy/run/render -time, while leaving un-annotated properties alone.
We have used this to avoid duplicating entire configuration files (with the associated problems well known) AND to reduce repetition. The technique is also perfect for internationalization (i18n) -- even within the same file, if desired.
Example, snippet of pre-processed JSON config:
var config = {
'ver': '1.0',
'help': {
'BLURB': 'This pre-production environment is not supported. Contact Development Team with questions.',
'PHONE': '808-867-5309',
'EMAIL': 'coder.jen#lostnumber.com'
},
'help#www.productionwebsite.com': {
'BLURB': 'Please contact Customer Service Center',
'BLURB#fr': 'S\'il vous plaît communiquer avec notre Centre de service à la clientèle',
'BLURB#de': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
'PHONE': '1-800-CUS-TOMR',
'EMAIL': 'customer.service#productionwebsite.com'
},
}
... and post-processed (in this case, at render time) given dynamic, browser-environment-known location.hostname='www.productionwebsite.com' and navigator.language of 'de'):
prefer(config,['www.productionwebsite.com','de']); // prefer(obj,string|Array<string>)
JSON.stringify(config); // {
'ver': '1.0',
'help': {
'BLURB': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
'PHONE': '1-800-CUS-TOMR',
'EMAIL': 'customer.service#productionwebsite.com'
}
}
If a non-annotated ('base') property has no competing annotated property, it is left alone (presumably global across environments) otherwise its value is replaced by an annotated value, if the suffix matches one of the inputs to the preference/discrimination function. Annotated properties that do not match are dropped entirely.
You can mix and match this behaviour to annotate configuration to achieve distinctions of global, default, specific that are (assuming you're sensible) readable with zero/minimal duplication.
The single, recursive prefer() function (as we're calling it, lacking the need or desire to make an entire project/framework out of it) we've developed so far (see jsFiddle, with inline docs) goes a bit further than this simple example, and (explained in greater detail here) handles deeply-nested configuration objects, as well as preferential ordering and (if you need to stay flat) combination of suffixes.
The function relies on JS ability to reference object properties as strings, dynamically, and tolerate # and & delimiters in property names which are not valid in dot-notation syntax but consequently (help) prevent developers from breaking this technique by accidentally referring to pre-processed/annotated attributes in code (unless they, non-conventionally don't prefer to use dot-notation.)
We have yet to have this break anything for us, nor have we been schooled on any fundamental flaws of this technique, beyond irresponsible/unintended usage or investment/fondness for existing frameworks/techniques that pre-exist. We have also not profiled it for performance (we only tend to run this once per build/session, etc.) so in your own usage, YMMV.
Most configurations transmitted client-side of course would not want to contain sensitive pre-production values, so one could (should!) use the same function to generate a production-only version (with no annotations) in pre-deploy, while still enjoying a SINGLE configuration file upstream in your process.
Further, if you're doing this for i18n, you may not want the entire wad going over the wire, so could process it server-side (cached or live, etc.) or pre-process it in build/deploy by splitting into separate files, but STILL enjoying a single source of truth as early in your workflow as possible.
We have not explored implementing the same function in Java (or C#, PERL, etc.) assuming it's even possible (with some exotic reflection maybe?) but a build environment that includes NodeJS could farm that step out easily.
Well if it suits your needs and you have no problem of storing the connection strings in the source control repository, you could create files like:
appsettings.dev.json
appsettings.qa.json
appsettings.staging.json
And choose the right one in the deployment script and rename it to the actual appsettings.json, which is then read by your app.