reference DTS.Variables in other classes in SSIS script task - ssis

I have an SSIS package which has a script task. It has of course the usual Script main class file, it uses a couple of web services so I used the WSDL command line too to generate a couple of proxy classes for those in the project. All works fine.
I defined a couple of read-only User:: variables to be used by the script task which define the URL paths of the two web services.
Problem : in the two web service proxy classes I seem not to have access to the Dts variables collection. I've tried adding the using Microsoft.SqlServer.Dts.Runtime; to each of the proxy classes but still cannot access those Dts variables within the proxy classes.
Is there a way to do this?

I was able to pass the variables to a class constructor by passing the ScriptObjectModel.
// in the ScriptMain class
YourWsClass ws = new YourWsClass(Dts);
//in the WS class
using Microsoft.SqlServer.Dts.Tasks.ScriptTask;
class YourWsClass
{
public YourWsClass(ScriptObjectModel dts)
{
string _v = (string)dts.Variables["User::YourVariable"].Value;
}
}

You won't be able to access the variables directly anywhere else than in the ScriptMain class. You have to pass the variable to your proxy class when you instantiate it.
// in the ScriptMain class
YourWsClass ws = new YourWsClass(Dts.Variables["User::YourVariable"].Value.ToString();
class YourWsClass
{
public YourWsClass(String v)
{
_v = v;
}
}

Related

Is it possible to add Junit5 extensions programmatically to a #TestTemplate test using #RegisterExtension?

Using Junit version 5.9.2 I am trying to programmatically add parameter resolvers extension for a test class constructor with a #TestTemplate annotation.
I am trying to add the extensions programmatically using #RegisterExtension.
Example:
public class MyTestClass {
#RegisterExtension
static final TestDependencyResolver resolverExt = new TestDependencyResolver(/*...*/);
private final TestDependency dependency;
public MyTestClass(TestDependency dependency) {
this.dependency = dependency;
}
#TestTemplate
#ExtendWith(SomeContextProvider.class)
void test() {
//...
}
}
I have tried:
making resolverExt field non static
Movine #ExtendWith(SomeContextProvider.class) to class level
And other possible combinations of 1 and 2.
In all cases the ctor parameter dependency is not injected and TestDependencyResolver::resolveParameter is not called, which to my understanding means the object was created without/before registering TestDependencyResolver, please correct me if I am wrong.
Is what I am trying to achieve possible? thanks.
Turns out the issue was not Junit5 but TestTemplateInvocationContextProvider I was using.
I used PactVerificationInvocationContextProvider which seems to have a bug and throws NullPointerException when resolving Ctor params, I have opened an issue for it if you want more details.

Example on how to wire up durable function dependency injection

Having successfully created and run a simple Azure Durable Function in Visual Studio 2017, I want to introduce logging.
The Visual Studio project template generates the static HttpStart class with a
Run method containing an optional parameter of type Microsoft.Extensions.Logging.ILogger.
I have no idea how to hook up dependency injection into a durable function project. Can anyone point me to an example on how to achieve this?
It looks to me like I will need some class, inside which I will need to use the Microsoft.Extensions.Logging.LoggingFactory.CreateLogger() method.
I imagine that this logic will need to be within a container class that is hooked into the run time pipeline using HostBuilder in some way (similar to using WebHostBuilder in static main method).
Thank you
#Thomas pointed me to examples I used to extract code that allows dependency injection to work when writing a durable function project:
using System.IO;
using System.Reflection;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog;
using NLog.Extensions.Logging;
using tmetadastoreFnApp;
using Willezone.Azure.WebJobs.Extensions.DependencyInjection;
using ILogger = Microsoft.Extensions.Logging.ILogger;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
[assembly: WebJobsStartup(typeof(Startup))]
namespace tmetadastoreFnApp
{
internal class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder) =>
builder.AddDependencyInjection(ConfigureServices);
private void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ILoggerFactory, LoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
services.AddLogging((builder) => builder.SetMinimumLevel(LogLevel.Trace));
var serviceProvider = services.BuildServiceProvider();
var loggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
loggerFactory.AddNLog(new NLogProviderOptions { CaptureMessageTemplates = true, CaptureMessageProperties = true });
var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
LogManager.LoadConfiguration(Directory.GetParent(dir) + "\\nlog.config");
}
}
}

Configuration of asp.net core using settings

I'm evaluating asp.net core and .net core and I'm not yet sure about some things. In the past it was possible to configure many components using the web.config out of the box.
To name some examples:
There was the membership-provider and I could implement many providers but I was able ton configure later which provider should be used. This was dependend of the use-case. Now I should use asp.net identity - but I can only find configurations that are performed in sourcecode.
Same for authentication. I can define "CookieAuthentication" and have to set the name, loginpath or the timeout within sourcecode. In the past I was able to set timeout, etc... via web.config.
Is there any way to configure partially these things out of the box from a config-file? Or is this not supported anymore and I have to implement this configuration on my own? In the past this was a really comfortable way.
In ASP.NET Core, Web.config file is used ONLY for IIS configuration, you cannot use it for application configuration, but there are new, better, more flexible configuration options that you can use.
There are multiple configuration sources that you can use, but in this example I'm using json. These examples are from working code in my SimpleAuth project.
You can configure things in startup from configuration files.
First you add a config file in json format that maps to your class. You can see my example class here, and the json file it maps from here
builder.AddJsonFile("simpleauthsettings.json", optional: true);
Then, in the ConfigureServices method you configure your class to be wired up from the config system as shown
services.Configure<SimpleAuthSettings>(Configuration.GetSection("SimpleAuthSettings"));
Then you add an IOptions accessor of your class to the method signature of the Configure method in the Startup.cs
The Dependency Injection will inject it into that method for you so you can use it there to configure things. Specifically I'm setting the cookie authentication scheme and name from my settings object.
The noteworthy part is that you can add whatever you want to the Configure method signature, and as long as it is something that has been registered in the ConfigureServices method, the DI will be able to inject it for you.
public class Startup
{
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
// this file is the custom configuration file to hydrate my settings from
builder.AddJsonFile("simpleauthsettings.json", optional: true);
....
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
....
services.Configure<SimpleAuthSettings>(Configuration.GetSection("SimpleAuthSettings"));
....
}
// note that the DI can inject whatever you need into this method signature
// I added IOptions<SimpleAuthSettings> authSettingsAccessor to the method signature
// you can add anything you want as long as you register it in ConfigureServices
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory,
IOptions<SimpleAuthSettings> authSettingsAccessor
)
{
...
// Add cookie-based authentication to the request pipeline
SimpleAuthSettings authSettings = authSettingsAccessor.Value;
var ApplicationCookie = new CookieAuthenticationOptions
{
AuthenticationScheme = authSettings.AuthenticationScheme,
CookieName = authSettings.AuthenticationScheme,
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/Login/Index"),
Events = new CookieAuthenticationEvents
{
//OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync
}
};
app.UseCookieAuthentication(ApplicationCookie);
// authentication MUST be added before MVC
app.UseMvc();
}
}

Why is this groovy code throwing a MultipleCompilationErrorsException?

I have the following groovy code :
class FileWalker {
private String dir
public static void onEachFile(String dir,IAction ia) {
new File(dir).eachFileRecurse {
ia.perform(it)
}
}
}
walker = new FileWalker()
walker.onEachFile(args[0],new PrintAction())
I noticed that if I place a def in front of walker , the script works. Shouldn't this work the way it is now ?
You don't need a def in groovyConsole or in a groovy script. I consider it good programming practice to have it, but the language will work without it and add those types of variables to the scripts binding.
I'm not sure about the rest of your code (as it won't compile as you've posted it). But you either have a really old version of groovy or something else is wrong with your config or the rest of your code.
With the addition of a stub for the missing IAction interface and PrintAction class, I'm able to get it to run without modification:
interface IAction {
def perform(obj)
}
class PrintAction implements IAction{
def perform(obj) {
println obj
}
}
class FileWalker {
private String dir
public static void onEachFile(String dir,IAction ia) {
new File(dir).eachFileRecurse {
ia.perform(it)
}
}
}
walker = new FileWalker()
walker.onEachFile(args[0],new PrintAction())
I created a dummy directory with "foo/bar" and "foo/baz" files.
If I save it to "walkFiles.groovy" and call it from the command line with
groovy walkFiles.groovy foo
It prints:
foo/bar
foo/baz
This is with the latest version of groovy:
groovy -v
Groovy Version: 1.6-RC-3 JVM: 1.5.0_16
In scripting mode (or via "groovyConsole"), you need a declaration of walker with "def" before using it. A Groovy script file is translated into a derivative class of class Script before it get compiled. So, every declaration needs to be done properly.
On the other hand, when you're running a script in "groovysh" (or using an instance of class GroovyShell), its mechanism automatically binds every referencing object without the need of declaration.
updated:
My above answer would be wrong as I decompiled a .class of Groovy and found that it's using a binding object inside the script as well. Thus my first paragraph was indeed wrong.

Access to global application settings

A database application that I'm currently working on, stores all sorts of settings in the database. Most of those settings are there to customize certain business rules, but there's also some other stuff in there.
The app contains objects that specifically do a certain task, e.g., a certain complicated calculation. Those non-UI objects are unit-tested, but also need access to lots of those global settings. The way we've implemented this right now, is by giving the objects properties that are filled by the Application Controller at runtime. When testing, we create the objects in the test and fill in values for testing (not from the database).
This works better, in any case much better than having all those objects need some global Settings object --- that of course effectively makes unit testing impossible :) Disadvantage can be that you sometimes need to set a dozen of properties, or that you need to let those properties 'percolate' into sub-objects.
So the general question is: how do you provide access to global application settings in your projects, without the need for global variables, while still being able to unit test your code? This must be a problem that's been solved 100's of times...
(Note: I'm not too much of an experienced programmer, as you'll have noticed; but I love to learn! And of course, I've already done research into this topic, but I'm really looking for some first-hand experiences)
You could use Martin Fowlers ServiceLocator pattern. In php it could look like this:
class ServiceLocator {
private static $soleInstance;
private $globalSettings;
public static function load($locator) {
self::$soleInstance = $locator;
}
public static function globalSettings() {
if (!isset(self::$soleInstance->globalSettings)) {
self::$soleInstance->setGlobalSettings(new GlobalSettings());
}
return self::$soleInstance->globalSettings;
}
}
Your production code then initializes the service locator like this:
ServiceLocator::load(new ServiceLocator());
In your test-code, you insert your mock-settings like this:
ServiceLocator s = new ServiceLocator();
s->setGlobalSettings(new MockGlobalSettings());
ServiceLocator::load(s);
It's a repository for singletons that can be exchanged for testing purposes.
I like to model my configuration access off of the Service Locator pattern. This gives me a single point to get any configuration value that I need and by putting it outside the application in a separate library, it allows reuse and testability. Here is some sample code, I am not sure what language you are using, but I wrote it in C#.
First I create a generic class that will models my ConfigurationItem.
public class ConfigurationItem<T>
{
private T item;
public ConfigurationItem(T item)
{
this.item = item;
}
public T GetValue()
{
return item;
}
}
Then I create a class that exposes public static readonly variables for the configuration item. Here I am just reading the ConnectionStringSettings from a config file, which is just xml. Of course for more items, you can read the values from any source.
public class ConfigurationItems
{
public static ConfigurationItem<ConnectionStringSettings> ConnectionSettings = new ConfigurationItem<ConnectionStringSettings>(RetrieveConnectionString());
private static ConnectionStringSettings RetrieveConnectionString()
{
// In .Net, we store our connection string in the application/web config file.
// We can access those values through the ConfigurationManager class.
return ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["ConnectionKey"]];
}
}
Then when I need a ConfigurationItem for use, I call it like this:
ConfigurationItems.ConnectionSettings.GetValue();
And it will return me a type safe value, which I can then cache or do whatever I want with.
Here's a sample test:
[TestFixture]
public class ConfigurationItemsTest
{
[Test]
public void ShouldBeAbleToAccessConnectionStringSettings()
{
ConnectionStringSettings item = ConfigurationItems.ConnectionSettings.GetValue();
Assert.IsNotNull(item);
}
}
Hope this helps.
Usually this is handled by an ini file or XML configuration file. Then you just have a class that reads the setting when neeed.
.NET has this built in with the ConfigurationManager classes, but it's quite easy to implement, just read text files, or load XML into DOM or parse them by hand in code.
Having config files in the database is ok, but it does tie you to the database, and creates an extra dependancy for your app that ini/xml files solve.
I did this:
public class MySettings
{
public static double Setting1
{ get { return SettingsCache.Instance.GetDouble("Setting1"); } }
public static string Setting2
{ get { return SettingsCache.Instance.GetString("Setting2"); } }
}
I put this in a separate infrastructure module to remove any issues with circular dependencies.
Doing this I am not tied to any specific configuration method, and have no strings running havoc in my applications code.