how to use different profile for dev and production in office vsto add-in development - vsto

When we dev/test our add-in, we need to request request http://dev.xx.com. and after release, in production we need to change the url to http://prod.xx.com.
How can we do this?
===
I'm new to vsto development and c#. I looked config file(in fact Settings.settings) way. But in fact i don't want the users to "config" it. It't better if I can build out two different versions in one click ervery time, and give one to testers and another to the end user.
When I devloping server-side springboot applications, I use 3 different config file and one single jar. And give the different config file and same sigle jar to different persons. This way at least we can confirm that the applicaiton (jar) is the same for test and deploy.
But the "Settings.settings" seems binded to the "solution" in vs. The pre processor seems not good enough, seems that it binded to the "solution" too. I have to change it in the "Properties" every time before I build the project? Or I need to create more "Solutions"?
Maybe I did't look that deep enough, I will keep looking
=== SOLVED
We finaly solved (partly) using Conditional compilation
#if DEBUG
const string baseUrl = "192.168.20.101:8001/api";
#endif
#if (!DEBUG)
const string baseUrl = "xxx.com/api";
#endif
one small issue is that we need to distribute debug package to our test team.

Related

Filtering out assets from precaching in create-react-app

I'm using React 17 with cra-template-pwa to create a PWA. One of my UI libraries has several hundred static image resources that all get preloaded in the PWA (and I don't use most of them). This causes a long delay in enabling the PWA, and even causes Lighthouse to crash. I'm looking at various approaches to fixing the problem, but for a quick fix just to run lighthouse, I'd like to just disable precaching. I haven't been able to find concrete info how to do this. Any advice?
The cleanest solution would entail using the exclude option in the workbox-webpack-plugin configuration, but that requires ejecting in create-react-app.
Something you can do without ejecting, though, is to explicitly filter out entries from the injected self.__WB_MANIFEST array before passing the value to precacheAndRoute().
Your service-worker.js could look something like:
import {precacheAndRoute} from 'workbox-precaching';
// self.__WB_MANIFEST will be replaced with an
// Array<{url: string, revision: string}> during the build process.
// This will filter out all manifest entries with URLs ending in .jpg
// Adjust the criteria as needed.
const filteredManifest = self.__WB_MANIFEST.filter((entry) => {
return !entry.url.endsWith('.jpg');
});
precacheAndRoute(filteredManifest);
The downsides of this approach is that your service-worker.js file will be a bit larger than necessary (since it will include inline {url, revision} entries that aren't needed), and that you'll end up triggering the service worker update flow more than strictly necessary, if the contents of one of your images changes. Those unnecessary service worker updates won't actually harm anything or change the behavior of your web app, though.

How to configure cache folder for SourceDiskCache?

I understand from the documentation that the SourceDiskCache folder cannot be configured using the XML configuration file and is only available "through code installation". However I can't figure out how!
I need to configure a custom folder. I have tried a few different things, with different results (both in Application_Start):
This doesn't throw an error, but uses the default folder (/cache)
var sourceDiskCachePlugin = new SourceDiskCachePlugin {VirtualCacheDir = "~/App_Data/cache"};
Config.Current.Plugins.GetOrInstall(sourceDiskCachePlugin);
This (and most other variations I have tried) throws the error "SourceDiskCache settings may not be adjusted after it is started."
new SourceDiskCachePlugin().Install(Config.Current);
Config.Current.Plugins.Get<SourceDiskCachePlugin>().VirtualCacheDir = "~/App_Data/cache";
How can I configure this?
Also, the documentation states that SourceDiskCache is in beta - is this still the case, and will XML configuration ever be available?
This would be the normal way to configure and install it:
var plugin = new SourceDiskCachePlugin()
plugin.VirtualCacheDir = "~/App_Data/cache";
plugin.Install(Config.Current);
If your code is running more than once, use Config.Current.Plugins.GetOrInstall(plugin); It's best if you only install the plugin during Application_Start.
However, approach #1 from your question should work equally well, as long as you've set the right NTFS permissions on App_Data.

Support for multiple environments in your windows store app

I have been working on a Windows Store app where I have to support multiple configuration parameters for my app. One of the parameters is the URL the app is talking to.
For example development environment, test, acceptance and finally production.
One of the things i'm currently thinking about is what is the most efficient way of supporting all these environments with the least effort. Because there isn't some kind of config file that we can change to update these parameters I came up with some ideas. I'm curious about other options that I might have not seen.
Here are the things I came up with:
1
Adding multiple configuration to the app and than using them in code to get the correct parameter like this:
private string webserviceUrl;
#if DEV
webserviceUrl = "devUrl";
#elif TEST
webserviceUrl = "testUrl";
#endif
2
With the approach in number 1 there are a few more options available like including a config xml file bases on the configuration, or fetching configuration settings from a webservice the first time the app is running.
3
Using a branch/merge strategy and update the config files in the branch. Advantage is that the code is clean and only contains the settings it needs for the build it's created for. And the package can be build by the build server. Disadvantage is that you need to branch/merge alot.
The last option feels like the most 'clean' solution to do this. Am I missing any options, or do you have experience with any of these methods? What would you prefer?
I think the assumption is that apps in the store will always point to production.
But, in saying that, I'm facing the same issue as we're side loading the application onto devices that we control, and not using the Windows Store at all.
To answer your question, I prefer option 1.
Option 2 and the xml/json config file seems like the best option though.
The webservice option probably won't work. What webservice URL do you use? And how will it work if you want some instances pointing to different environments as they will all be fetching the config from the same URL.
Another option you might want to consider would be options in the settings charm menu. For example, use radio buttons for the environments, and allow the user to configure which environment they want to target.
The issue would be locking it down in production for end users so that it isn't modifiable any more. Perhaps once "PROD" radio is selected, all the radio buttons are then hidden.
If you're deploying the application through side loading, then these settings could probably be configured during the install process.
I'd be interested to hear other opinions as well. This is also an old question, so I'd like to know what solution you decided on implementing.

Worklight Direct update

Does anybody know what if direct update updates everything that lives in the common directory structure. I used the same code base for multiple apps, the only change being certain settings within a js file that tells the application how to act. Is there a directory i can put that js file that would be safe from the direct update feature?
I cant seen to find any specific information on IBM's website.
I think you guys need to be careful which terms you are using in order to not confuse people who may be looking for similar help.
Environments are specific to the OS you are using. iOS, Blackberry, Android, and etc. environments.
Skins are based on the environment, and aren't generic to all platform. When you create a skin you must choose which environment you are running in.
So to correct some, direct updates will update all skin resources in targeted environments.
For example: You have an app with Android and iOS versions
When you create skins, you are creating essentially a responsive type of design to your parameters. For instance, if you have a 2.3 vs 4.2 Android OS, you can set a look and feel for both. However, these utilize a single web resource base. The APK would be the same for both versions of the app (by default) and have 2 available skins. On runtime utilizing IBM Worklight's 'Runtime Skinning' (hence the name) it goes through the parameter check for the OS and loads that skins overriding web code.
You could technically override all of the web code to be completely different for both skins, but that would be bulky and inefficient.
When you direct update you are updating all the resources of that particular environment (to include both skins), not the common folder/environment.
So an updated Android (both skins) would have updated web resources (if you deployed the android wlapp) and an iOS version would stay the same.
If you look at the Android project after build (native -> assets -> www -> default or skin) you can find the shared web resources generated by the common environment. However that is only put there every time you do a new build.
In the picture, I have an older version of the Android built for both skins on the left. On the right is a preview of the newer common resources after deploying only the common.wlapp. So you can see that they are separate.
Sorry if it was long winded, but I thought I would be thorough.
To answer the original question, have you thought of having all the parameters of the store loaded from user input or a setup? If you are trying to connect to 3 different store, create some form for settings control that will access different back ends or specific adapters. You could also create 3 different config.js that load depending on the parameters that you set so that you set. The other option is to set different versions of your apps specific to the store.
Example. Version 1.11, 1.12,1.13 can be 3 versions of the same app for store 1, 2, & 3. They can be modified and change and have 3 sets of web resources. When you need to update, jump up to version 1.21, 1.22,1.23. It seems a bit of a work around, but it may be your best bet at getting 3 versions of the same app to fall within the single application category. (keep 3 config.js types for modifying for the 3 stores).
To the best of my knowledge Direct Update will update every web resource of the skin you're using (html, css, js). However, I'm no expert with it.
If you're supporting only Android and iOS applications and need a way to store settings I recommend JSONStore. Otherwise look into Cordova Storage, Local Storage or IndexedDB.
Using a JSONStore collection called settings will allow you to store data on disk inside the app's directory. It will persist until you call one of the removal methods like destroy or until the application is uninstalled. There are also ways of linking collections to Worklight Adapters to pull/push data from/to a server. The links below will provide further details.
the only change being certain settings within a js
Create a collection for your settings:
var options = {};
options.onSuccess = function () {
//... what to do after init finished
};
options.onFailure = function () {
//... what to do if init fails
}
var settings = WL.JSONStore.initCollection('settings',
{background: 'string', itemsPerPage: 'number'}, options);
You can add new settings after initCollection onSuccess has been called:
settings.add({background: 'red', itemsPerPage: 20}, options);
You can find settings stored after initCollection onSuccess has been called:
settings.findAll({onSuccess: function (results) {
console.log(JSON.stringify(results));
}});
You can read more about JSONStore in the Getting Started Modules. See Modules: 7.9, 7.10, 7.11, 7.12. There is further information inside the API Documentation in IBM InfoCenter. The methods described above are: initCollection, add and findAll.
Since version 5.0.3 I think, direct update will not update all the webresources, only those of the skin you are using.
say you have skin def and skin skin2
you are on def
make change to def on the server -> you will get a direct update for
def only
make change to skin2 on server-> no direct update for you.
you are on skin2:
make change to skin2 on server -> direct update for skin2 only
make change to def javascript which also resides on skin2 ( and therefor end result is def+skin2 concatination), update only skin2
make change to def,just to a picture(also checking pic extension from application-descriptor: ") -> no direct update
Thats how direct update works.
Please also share some more details about what is the problem, I see you use a js file, where do you change it? what do you mean excatly, give a better (simplified) real life example, because it is unclear what you are trying.

NAnt, MbUnit, CruiseControl, Selenium - passing settings to the test assembly

I am putting together some ideas for our automated testing platform and have been looking at Selenium for the test runner.
I am wrapping the recorded Selenium C# scripts in an MbUnit test, which is being triggered via the MbUnit NAnt task. The Selenium test client is created as follows:
selenium = new DefaultSelenium("host", 4444, "*iexplore", "http://[url]/");
How can I pass the host, port and url settings into the test so their values can be controlled via the NAnt task?
For example, I may have multiple Selenium RC servers listening and I want to use the same test code passing in each server address instead of embedding the settings within the tests themselves.
I have an approach mocked up using a custom NAnt task I have written but it is not the most elegant solution at present and I wondered if there was an easier way to accomplish what I want to do.
Many thanks if anyone can help.
Thanks for the responses so far.
Environment variables could work, however, we could be running parallel tests via a single test assembly so I wouldn't want settings to be overwritten during execution, which could break another test. Interesting line of thought though, thanks, I reckon I could use that in other areas.
My current solution involves a custom NAnt task build on top of the MbUnit task, which allows me to specify the additional host, port, url settings as attributes. These are then saved as a config file within the build directory and then read in by the test assemblies. This feels a bit "clunky" to me as my tests need to inherit from a specific class. Not too bad but I'd like to have less dependencies and concentrate on the testing.
Maybe I am worrying too much!!
I have a base class for all test fixtures which has the following setup code:
[FixtureSetUp]
public virtual void TestFixtureSetup ()
{
BrowserType = (BrowserType) Enum.Parse (typeof (BrowserType),
System.Configuration.ConfigurationManager.AppSettings["BrowserType"],
true);
testMachine = System.Configuration.ConfigurationManager.AppSettings["TestMachine"];
seleniumPort = int.Parse (System.Configuration.ConfigurationManager.AppSettings["SeleniumPort"],
System.Globalization.CultureInfo.InvariantCulture);
seleniumSpeed = System.Configuration.ConfigurationManager.AppSettings["SeleniumSpeed"];
browserUrl = System.Configuration.ConfigurationManager.AppSettings["BrowserUrl"];
targetUrl = new Uri (System.Configuration.ConfigurationManager.AppSettings["TargetUrl"]);
string browserExe;
switch (BrowserType)
{
case BrowserType.InternetExplorer:
browserExe = "*iexplore";
break;
case BrowserType.Firefox:
browserExe = "*firefox";
break;
default:
throw new NotSupportedException ();
}
selenium = new DefaultSelenium (testMachine, seleniumPort, browserExe, browserUrl);
selenium.Start ();
System.Console.WriteLine ("Started Selenium session (browser type={0})",
browserType);
// sets the speed of execution of GUI commands
if (false == String.IsNullOrEmpty (seleniumSpeed))
selenium.SetSpeed (seleniumSpeed);
}
I then simply supply the test runner with a config. file:
For MSBuild I use environment variables, I create those in my CC.NET config then they would be available in the script. I think this would work for you too.
Anytime I need to integrate with an external entity using NAnt I either end up using the exec task or writing a custom task. Given the information you posted it would seem that writing your own would indeed be a good solution, However you state you're not happy with it. Can you elaborate a bit on why you don't think you current solution is an elegant one?
Update
Not knowing internal details it seems like you've solved it pretty well with a custom task. From what I've heard, that's how I would have done it.
Maybe a new solution will show itself in time, but for now be light on yourself!