I have code to execute my handler/command, and it reaches here:
#Execute
public Object execute(Shell shell) {
System.out.println("Executing login!");
return null;
}
However, I cannot find the injection service to provide me the parameters I passed in the command.
I tried:
#Execute
public Object execute(ExecutionEvent event)
But it doesn't even see this method, and I suspect it's because that's not even an e4.* class. I am aware of Eclipse RCP 4 - Handler method parameters but it doesn't tell me which service the command parameters are, e.g..:
ParameterizedCommand myCommand = commandService.createCommand("mycommand.login", credentials);
Object result = handlerService.executeHandler(myCommand);
Where are my values from the credentials map?
You can get the whole ParameterizedCommand injected in the handler using:
#Execute
public void execute(ParameterizedCommand command)
Or you can get the individual parameters using their ids:
#Execute
public void execute(#Named("parameter id") String parameter)
Related
I am working on my first Blazor Server application, which is also my first Entity Framework Core application. I am wanting to set up a background service which, once a day in the early morning, checks the database to see if any of a certain record type has been added with yesterday's date. If so, the relevant records are pulled, formatted, and then emailed to a stakeholder.
I have the EF, formatting, and emailing code working just fine when I trigger the report by manually visiting the page. The problem that I have is how to provide the background service with a DbContextFactory so that the EF and related code can execute.
Up to this point I've always used Razor-based dependency injection to inject the IDbContextFactory via an inject IDbContextFactory<OurAppContext> DbFactory at the top of the page, and then accessed the DbFactory via the DbFactory variable.
However, background services are (according to this Microsoft tutorial) set up through Program.cs, so I don't have access to Razor-based dependency injection there.
I have set up my background service (what I call the PhaseChangeReportService) as indicated in the above link, and it dutifully outputs to the console every 10 seconds that it is running with an updated execution count. I don't fully understand what's going on with the various layers of indirection, but it appears to be working as Microsoft intended.
I noted that the constructor for the background service takes in an ILogger as a parameter, specifically:
namespace miniDARTS.ScopedService
{
public sealed class PhaseChangeReportService : IScopedProcessingService
{
private int _executionCount;
private readonly ILogger<PhaseChangeReportService> _logger;
public PhaseChangeReportService(ILogger<PhaseChangeReportService> logger)
{
_logger = logger;
}
public async Task DoWorkAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
++_executionCount;
_logger.LogInformation("{ServiceName} working, execution count: {Count}", nameof(PhaseChangeReportService), _executionCount);
await Task.Delay(10_000, stoppingToken);
}
}
}
}
I was (and am) confused that the constructor is never referenced within Visual Studio, but when I drop a breakpoint on its one line of code it is hit. I tried modifying this constructor's signature so that it took in an IDbFactory<OurAppContext> as well, so that whatever dark magic is allowing an ILogger<BackgroundServiceType> to come in for assignment to _logger might bring in a DbFactory<OurAppContext> as well, like so:
private readonly ILogger<PhaseChangeReportService> _logger;
private readonly IDbContextFactory<miniDARTSContext> _dbContextFactory;
public PhaseChangeReportService(ILogger<PhaseChangeReportService> logger, IDbContextFactory<miniDARTSContext> dbContextFactory)
{
_logger = logger;
_dbContextFactory = dbContextFactory;
}
However, doing so just led to the constructor breakpoint being skipped over and not breaking, with no exception being thrown or any console output of any kind (i.e. the prior execution count console output no longer showed up). So, I gave up on that approach.
Here is the relevant section of Program.cs:
// Configure the database connection.
string connectionString = builder.Configuration.GetConnectionString("miniDARTSContext");
var serverVersion = new MySqlServerVersion(new Version(8, 0, 28));
builder.Services.AddDbContextFactory<miniDARTSContext>(options => options.UseMySql(connectionString, serverVersion), ServiceLifetime.Scoped);
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<ScopedBackgroundService>();
services.AddScoped<IScopedProcessingService, PhaseChangeReportService>();
})
.Build();
host.RunAsync();
Here's IScopedProcessingService.cs:
namespace miniDARTS.ScopedService
{
public interface IScopedProcessingService
{
Task DoWorkAsync(CancellationToken stoppingToken);
}
}
And here's ScopedBackgroundService.cs:
namespace miniDARTS.ScopedService;
public sealed class ScopedBackgroundService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<ScopedBackgroundService> _logger;
public ScopedBackgroundService(IServiceProvider serviceProvider, ILogger<ScopedBackgroundService> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation($"{nameof(ScopedBackgroundService)} is running.");
await DoWorkAsync(stoppingToken);
}
private async Task DoWorkAsync(CancellationToken stoppingToken)
{
_logger.LogInformation($"{nameof(ScopedBackgroundService)} is working.");
using (IServiceScope scope = _serviceProvider.CreateScope())
{
IScopedProcessingService scopedProcessingService = scope.ServiceProvider.GetRequiredService<IScopedProcessingService>();
await scopedProcessingService.DoWorkAsync(stoppingToken);
}
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation($"{nameof(ScopedBackgroundService)} is stopping.");
await base.StopAsync(stoppingToken);
}
}
I'm confident I'm misunderstanding something relatively fundamental here when it comes to services / dependency injection, but my Googling and review of past StackOverflow answers has not turned up anything I can run with.
The IDbContextFactory is an interface that is used for creating instances of a DbContext. When you add it to your services on program.cs for Blazor (services.AddDbContextFactory(parameters)), it implements the IDbContextFactory for you. This allows you to use the #inject IDbContextFactory<YourDbContext> DbFactory at the top of your razor components and then within your code you can call the CreateDbContext method when you need to create an instance of the DbContext (ex. using var context = DbFactory.CreateDbContext()).
You can pass an injected DbContextFactory as a parameter from a razor component to a class, and then use that DbContextFactory in a method to create an instance of the DbContext (see constructor injection), but that still relies on the razor component to inject the DbContextFactory to begin with.
To create an instance of a DbContext independent of a razor component, you need to use the constructor for your DbContext. Your DbContext will have a public constructor with a DbContextOptions parameter (this is required to be able to use AddDbContextFactory when registering the factory service in program.cs). You can use this constructor to implement your own factory. If you aren't sure which options to use, you can check your program.cs to see what options you used there.
public class YourDbFactory : IDbContextFactory<YourDbContext>
{
public YourDbContext CreateDbContext()
{
var optionsBuilder = new DbContextOptionsBuilder<YourDbContext>();
optionsBuilder.UseSqlServer(#"Server=(localdb)\mssqllocaldb;Database=Test"));
return new YourDbContext(optionsBuilder);
}
}
Once you've created your own implementation of the IDbContextFactory interface, you can then use it in your code independent of razor components - for example in the background service class.
YourDbFactory DbFactory = new YourDbFactory();
using var context = DbFactory.CreateDbContext();
I have a test that takes in test data. When using nunit console app to run the test, is there a way I can specify the data to be used?
Eg:
[Test, TestCaseSource(typeof(TestData))]
public void ATest(string param1, int param2)
public class TestData : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return new object[] { "blah1 blah1", 1};
yield return new object[] { "blah2 blah2", 2};
}
}
I want to be able to run ATest with test data ["blah2 blah2", 2] only. If I run as follows:
nunit3-console.exe Tests.dll --test=ATest --workers=1 --noresult
it will run twice.
Just run...
nunit3-console.exe Tests.dll --test ATest("blah2 blah2", 2)
or
nunit3-console.exe Tests.dll --where "test~=blah2"
If that string is unique to all your tests.
Note that the first one may require some escaping of the quotes, depending on your operating system.
One way to do this would be through returning a TestCaseData object instead.
Something like this: (untested, so syntax might be a little off!)
[Test, TestCaseSource(typeof(TestData))]
public void ATest(string param1, int param2)
public IEnumerator GetEnumerator()
{
yield return new TestCaseData("blah1 blah1", 1).SetName("FirstTest");
yield return new TestCaseData("blah2 blah2", 2).SetName("SecondTest");
}
To run the first test, you would then use the command line:
nunit3-console.exe Tests.dll --test=YourNameSpace.ATest.FirstTest --workers=1 --noresult
Depending what you're doing, setting the category may be more suitable than the name. The docs page shows what's available: https://github.com/nunit/docs/wiki/TestCaseData
I'm currently working on a simple GWT project. One of the things I'd like to do is that when the page loads I can dynamically populate the contents of a ListBox based on certain criteria. I actually don't see any handlers for a ListBox to handle the initial render event but I see change handlers.
How does one populate a ListBox contents with data from the server side on pageload with GWT?
Right now I have a class that implements EntryPoint that has a
final ListBox fooList = new ListBox();
I also have a set of beans but I also have a class implementing RemoteService. Since I can't seem to get direct calls to my user defined packages directly in the EntryPoint (which makes sense) how do I populate that ListBox with server side content on initial page load? Right now I'm using a List but I figure if I cant get that to work I can get a DB call to work...
I've tried things in the EntryPoint like:
for (String name : FOOS) {
fooList.addItem(name, name);
}
However FOOS would derive from a server side data and the EntryPoint is supposed to be largerly limited to what can compile to JS! I can't get user defined classes to be recognized on that side as that string is the result of a set of user defined classes.
I also tried creating a method in the class implementing RemoteService that returns a ListBox. This also didn't compile when I tried to call this method. Perhaps I don't fully understand how to call methods in a RemoteService service implementing class.
I've searched a lot and I can't find anything that clearly explains the fundamentals on this. My background is much more ASP.NET and JSPs so perhaps I'm missing something.
I'm using GWT 2.6 is that is relevant.
The usual procedure is the following:
Create a bean class for the data you want to transmit between client and server. Let's call it MyBean.
Place MyBean in the shared package of your project.
This class has to implement either Serializable or IsSerializable, otherwise GWT will complain that it doesn't know how to transmit it.
Create your RemoteService that contains the method you want to use to transmit MyBean from/to the server.
Once you get your data on the client using an AsyncCallback and your RemoteService, fill the ListBox using your beans, e.g. by calling MyBean#getName() or MyBean#toString().
Success!
I based my example on the GWT sample project ( I named it example), just replace the classes and it should work :
public class Example implements EntryPoint {
/**
* Create a remote service proxy to talk to the server-side Greeting
* service.
*/
private final GreetingServiceAsync greetingService = GWT
.create(GreetingService.class);
/**
* This is the entry point method.
*/
public void onModuleLoad() {
final ListBox listBox = new ListBox();
RootPanel.get("sendButtonContainer").add(listBox);
greetingService.getSomeEntries(new AsyncCallback<String[]>() {
#Override
public void onSuccess(String[] result) {
for (int i = 0; i < result.length; i++) {
listBox.addItem(result[i]);
}
}
#Override
public void onFailure(Throwable caught) {
}
});
}
}
This is our EntryPoint, it creates a listbox and calls the server with a AsyncCallback to get some dynamic data. If the call is successfull (onSuccess), the data is written into the listbox.
The GreetingService interface define the synchronous methods, it is implemented in the GreetingServiceImpl class :
#RemoteServiceRelativePath("greet")
public interface GreetingService extends RemoteService {
String[] getSomeEntries() ;
}
The asynchronous counterpart is the GreetingServiceAsync interface, we used it before to call the server :
public interface GreetingServiceAsync {
void getSomeEntries(AsyncCallback<String[]> callback) ;
}
The GreetingServiceImpl class is located on the server. Here you could call for example a database:
#SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService {
#Override
public String[] getSomeEntries() {
String[] entries = { "Entry 1","Entry 2","Entry 3" };
return entries;
}
}
Now if you want to use some Bean/Pojo between the server and client, replace the String[] in each class/interface with the object name, put the class in the shared package and consider that it implements Serializable/IsSerializable.
What I wan to do is read parameterized values and use them in the before class to set up a webdriver for the bowser as soecified by the parameter, the run the tests in the browser. Then get the next browser and run the test in that browser and so on for all the other specified browsers. But I am getting null values in the before class for the parmeters. Can you do this in Junit or is there another way of doing this?
Thanks
#RunWith(value = Parameterized.class)
public class MultiBrowser {
private static WebDriver driver;
private static String browser;
//private static Dimension device;
private static String testData = "Testing";
private static String device;
#Parameters
public static Collection< Object[]> data() {
System.out.println("Inside parameter");
return Arrays.asList(new Object[][]{{"Firefox", "IPHONE4"},{"Chrome", "IPAD"},{"Ie", "SamsungGalaxy"}});
}
public MultiBrowser(String browser, String device){
System.out.println("Inside MultiBrowser = "+ browser+" " + device);
this.browser=browser;
this.device=device;
}
#BeforeClass
public static void dosetUp() throws Exception {
System.out.println("Doing setup before class..." + browser + device);
}
The technique you're using here won't work. #Parameters are injected through constructors, but your static #BeforeClass method is invoked before any constructor has been called, so those static fields will be null.
Your question is very similar to Creating a JUnit testsuite with multiple instances of a Parameterized test, and also Parameterized suites in Junit 4?; both answers suggest TestNG as a framework that is able to do this.
In JUnit, you could use the technique suggested by
How do I Dynamically create a Test Suite in JUnit 4?
to build a test suite dynamically and make do without using #Parameters.
Or, for a simpler but less efficient solution, move your setup code into a non-static #Before method and accept that it will run before every single test.
How to communicate user defined objects and user defined (checked) exceptions between Service and UI in JavaFX2?
The examples only show String being sent in to the Service as a property and array of observable Strings being sent back to the UI.
Properties seem to be defined only for simple types. StringProperty, IntegerProperty, DoubleProperty etc.
Currently I have a user defined object (not a simple type), that I want Task to operate upon and update with the output data it produced. I am sending it through the constructor of Service which passes it on through the constructor of Task. I wondered about the stricture that parameters must be passed in via properties.
Also if an exception is thrown during Task's operation, How would it be passed from Service to the UI? I see only a getException() method, no traditional throw/catch.
Properties http://docs.oracle.com/javafx/2/binding/jfxpub-binding.htm
Service and Task http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
Service javadocs http://docs.oracle.com/javafx/2/api/javafx/concurrent/Service.html#getException()
"Because the Task is designed for use with JavaFX GUI applications, it
ensures that every change to its public properties, as well as change
notifications for state, errors, and for event handlers, all occur on
the main JavaFX application thread. Accessing these properties from a
background thread (including the call() method) will result in runtime
exceptions being raised.
It is strongly encouraged that all Tasks be initialized with immutable
state upon which the Task will operate. This should be done by
providing a Task constructor which takes the parameters necessary for
execution of the Task. Immutable state makes it easy and safe to use
from any thread and ensures correctness in the presence of multiple
threads."
But if my UI only touches the object after Task is done, then it should be ok, right?
Service has a signature Service<V> the <V> is a generic type parameter used to specify the type of the return object from the service's supplied task.
Let's say you want to define a service which returns a user defined object of type Foo, then you can do it like this:
class FooGenerator extends Service<Foo> {
protected Task createTask() {
return new Task<Foo>() {
protected Foo call() throws Exception {
return new Foo();
}
};
}
}
To use the service:
FooGenerator fooGenerator = new FooGenerator();
fooGenerator.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
#Override public void handle(WorkerStateEvent t) {
Foo myNewFoo = fooGenerator.getValue();
System.out.println(myNewFoo);
}
});
fooGenerator.start();
If you want to pass an input value into the service each time before you start or restart it, you have to be a little bit more careful. You can add the values you want to input to the service as settable members on the service. These setters can be called from the JavaFX application thread, before the service's start method is invoked. Then, when the service's task is created, pass the parameters through to the service's Task's constructor.
When doing this it is best to make all information passable back and forth between threads immutable. For the example below, a Foo object is passed as an input parameter to the service and a Foo object based on the input received as an output of the service. But the state of Foo itself is only initialized in it's constructor - the instances of Foo are immutable and cannot be changed once created and all of it's member variables are final and cannot change. This makes it much easier to reason about the program, as you never need worry that another thread might overwrite the state concurrently. It seems a little bit complicated, but it does make everything very safe.
class FooModifier extends Service<Foo> {
private Foo foo;
void setFoo(Foo foo) { this.foo = foo; }
#Override protected Task createTask() {
return new FooModifierTask(foo);
}
private class FooModifierTask extends Task<Foo> {
final private Foo fooInput;
FooModifierTask(Foo fooInput) { this.fooInput = fooInput; }
#Override protected Foo call() throws Exception {
Thread.currentThread().sleep(1000);
return new Foo(fooInput);
}
}
}
class Foo {
private final int answer;
Foo() { answer = random.nextInt(100); }
Foo(Foo input) { answer = input.getAnswer() + 42; }
public int getAnswer() { return answer; }
}
There is a further example of providing input to a Service in the Service javadoc.
To return a custom user exception from the service, just throw the user exception during the service's task call handler. For example:
class BadFooGenerator extends Service<Foo> {
#Override protected Task createTask() {
return new Task<Foo>() {
#Override protected Foo call() throws Exception {
Thread.currentThread().sleep(1000);
throw new BadFooException();
}
};
}
}
And the exception can be retrieved like this:
BadFooGenerator badFooGenerator = new BadFooGenerator();
badFooGenerator.setOnFailed(new EventHandler<WorkerStateEvent>() {
#Override public void handle(WorkerStateEvent t) {
Throwable ouch = badFooGenerator.getException();
System.out.println(ouch.getClass().getName() + " -> " + ouch.getMessage());
}
});
badFooGenerator.start();
I created a couple of executable samples you can use to try this out.
Properties seem to be defined only for simple types. StringProperty, IntegerProperty, DoubleProperty etc. Currently I have a user defined object (not a simple type), that I want Task to operate upon and update with the output data it produced
If you want a property that can be used for your own classes try SimpleObjectProperty where T could be Exception, or whatever you need.
Also if an exception is thrown during Task's operation, How would it be passed from Service to the UI?
You could set an EventHandler on the Task#onFailedProperty from the UI with the logic with what to do on failure.
But if my UI only touches the object after Task is done, then it should be ok, right?
If you call it from your UI you are sure to be on the javaFX thread so you will be OK. You can assert that you're on the javaFX thread by calling Platform.isFxApplicationThread().