Grails: How do I create a static array - grails

I'm new to grails. I need to create a static array which needs to be filled with certain items on startup. i.e
public class kingUtil {
public static String[] overlordArray = new String[]
static def init() {
overlordArray[0] = "foos"
overlordArray[1] = "roh"
overlordArray[2] = "dah"
}
}
So I put the utility groovy class in sources and I intended to call init() from bootstrap.
However, bootstrap cannot recognize the class name, like it can't reach it or something. What's the best way to establish implement application-scope statics in grails.

Related

How to get the instance of an injected dependency, by its type using Umbraco.Core.Composing (Umbraco 8)

I need to find a way to get an instance of DataProcessingEngine without calling it's constractor.
I am trying to find a way to do so using the registered DataProcessingEngine in composition object (please see the following code). But I could not find a way to do so.
Anyone have a suggestion? Thanks in advance.
public class Composer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Register<IDataProcessingEngine, DataProcessingEngine>(Lifetime.Singleton);
//DataProcessingEngine dataProcessing = compostion.Resolve<IDataProcessingEngine>()??//no resolve function exists in Umbraco.Core.Composing
SaveImagesThread(dataProcessingEngine);
}
public Task SaveImagesThread(IDataProcessingEngine dataProcessingEngine)//TODO - decide async
{
string dataTimerTime = WebConfig.SaveProductsDataTimer;
double time = GetTimeForTimer(dataTimerTime);
if (time > 0)
{
var aTimer = new System.Timers.Timer(time);
aTimer.Elapsed += new ElapsedEventHandler(dataProcessingEngine.SaveImages);
aTimer.Start();
}
return default;
}
}
For all of you who are looking for a way to call a function (that's defined in another class in your code, an Engine or ...) from the composer(where the app starts) and want to avoid calling this function's class' constractor. I've found another way to do so:
public class QueuePollingHandler
{
[RuntimeLevel(MinLevel = RuntimeLevel.Run)]
public class SubscribeToQueuePollingHandlerComponentComposer :
ComponentComposer<SubscribeToQueuePollingHandler>
{ }
public class SubscribeToQueuePollingHandler : IComponent
{
private readonly IDataProcessingEngine _dataProcessingEngine;
public SubscribeToQueuePollingHandler(IDataProcessingEngine
dataProcessingEngine)
{
_dataProcessingEngine = dataProcessingEngine;
SaveImagesThread(_dataProcessingEngine);
}
public void SaveImagesThread(IDataProcessingEngine
dataProcessingEngine)
{
....
}
}
And the logic explenation: You create a class (SubscribeToQueuePollingHandlerComponentComposer from the example) and define its base class to be ComponentComposer<Class_that_inherits_IComponent>.
And when you start the application you could see that it gets to the registered class' constractor (SubscribeToQueuePollingHandler constructor).
That's the way that I found to be able to call a function right when the application starts without needing to call its class constractor and actualy use dependency injection.

Instantiating IOptions<> in xunit

I'm trying to write an xunit test for a class (in a .net Core project) that looks something like:
public Class FoodStore:IFoodStore
{
FoodList foodItems;
public FoodStore(IOptions<FoodList> foodItems)
{
this.foodItems = foodItems;
}
public bool IsFoodItemPresentInList(string foodItemId)
{
//Logic to search from Food List
}
}`
Note: FoodList is actually a json file, containing data, that is loaded and configured in the Startup class.
How can I write an xunit test with appropriate dependency injection to test the IsFoodItemPresentInList method ?
You can create an instance of IOptions<FoodList> using the Options.Create method:
var foodListOptions = Options.Create(new FoodList());
You could use OptionsWrapper<T> class to fake your configuration. Then you can pass in this object to your class that you want to test. That way you don't have to use DI or read the real configuration.
Something like this:
var myConfiguration = new OptionsWrapper<MyConfiguration>(new MyConfiguration
{
SomeConfig = "SomeValue"
});
var yourClass = new YourClass(myConfiguration);
I have encountered a similar problem (using xUnit), after some struggle, I worked it out.
The answer is so late, but should be helpful for others.
For your Question:
public Class FoodStoreTest
{
private readonly IConfigurationRoot _configuration;
private readonly IServiceProvider _serviceProvider;
public FoodStoreTest(){
// read Json
var configBuilder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
_configuration = configBuilder.Build();
// SetUp DI
var services = new ServiceCollection();
services.AddOptions(); // this statement is required if you wanna use IOption Pattern.
services.Configure<YuntongxunOptions>(_configuration.GetSection("yuntongxun"));
_serviceProvider = services.BuildServiceProvider();
}
[Fact]
public void GetFootItemOption()
{
IOption<FoodList> optionAccessor = _serviceProvider.GetService<IOptions<FoodList>>();
FoodList footListOptions = optionAccessor.value;
Assert.NotNull(footListOptions)
// ...
}
}
Also, you should copy "appSettings.json" to your project root folder.
In a unit test, you typically don't use Dependency Injection, since it's you who controls the creation of the tested object.
To supply a suitable object that implements IOptions<FoodList> you can implement a fake class with the desired behavior yourself, or use some mocking framework to configure the instance on the fly, for example Moq.
As suggested by the other answers, in your test class you can create an options instance just for testing.
You can do it like this;
public class FakeFoodList : IOptions<FoodList>
{
public FoodList Value
{
get
{
return new FoodList(); // TODO: Add your settings for test here.
}
}
}
And then call it like this;
var foodOptions = new FakeFoodList();
var foodStore = new FoodStore(foodOptions);
var response = foodStore.Act();
Assert.Equal("whatever", response);

Context Injection and BeforeFeature hook

I am trying to do some intial setup which sets up the environment for the scenarios under a particular feature. I clubbed the setup data in a separate class. I added a specflow hook file and modified it to serve as before feature hook. Then I tried using Context Injection. In the I created a private variable of the setup class and a constructor (taking an object of the setup class) for the BeforeScenario hook file.
The issue I am facing is that the BeforeFeature method has to static as per specflow. And if I make my private setup class static, then the constructor is not getting called.
Is what I am doing right? Or Is it even possible what I am trying to do?
[Binding]
public class BeforeFeature
{
private static SetUp setUp;
public BeforeFeature(SetUp setUpObject)
{
setUp = setUpObject;
}
[BeforeFeature]
public static void RunBeforeFeature()
{
//Some processing.
setUp.baseDir = "some data";
setUp.status = "some data"
}
}
You can tell SpecFlows context injection framework that you have an object it should use when a Step class asks for an instance in its constructor. This can be done like shown in the example:
[Binding]
public class BeforeFeature
{
private readonly IObjectContainer objectContainer;
private static SetUp setUp;
public BeforeFeature(IObjectContainer container)
{
this.objectContainer = objectContainer;
}
[BeforeFeature]
public static void RunBeforeFeature()
{
//Some processing.
setUp.baseDir = "some data";
setUp.status = "some data"
}
[BeforeScenario]
public void RunBeforeScenario()
{
objectContainer.RegisterInstanceAs<SetUp>(setUp);
}
}
You do the setup before the Scenario not the feature but if you only create the SetUp once and set its values in the [BeforeFeature] then you should get the same instance in each scenario so any modifications made there should stick (assuming this is what you want, otherwise just create a new SetUp in the BeforeScenario method)
As long as your Step classes now ask for a SetUp instance in the constructor they should get the one you placed in the container.

Autofac get decorated QueryHandler by convention based on constructor parameter name?

We inject IQueryHandler<TQUery,TResult> into our MVC controllers. We globally register all of these in the container
We have written a decorator that can cache the results of IQueryHandler.
We want to sometimes get cached reults and other times not from the same handler.
Is it possible to conditionally get a decorated handler based on the name of the constructor parameter. e.g. inject IQueryHandler<UnemployedQuery, IEnumerable<People>> cachedPeopleHandler if we prefix constructor parameter name with cached we actually get it wrapped with decorator?
Just trying to use a more convention over configuration approach to simplify things.
Yes it's possible to do it. Below is a simple working example on how you can achieve it:
class Program
{
public interface IQueryHandler{}
private class QueryHandler : IQueryHandler
{
}
private class CacheQueryHandler : IQueryHandler
{
}
public interface IService
{
}
private class Service : IService
{
private readonly IQueryHandler _queryHandler;
private readonly IQueryHandler _cacheQueryHandler;
public Service(IQueryHandler queryHandler, IQueryHandler cacheQueryHandler)
{
_queryHandler = queryHandler;
_cacheQueryHandler = cacheQueryHandler;
}
public override string ToString()
{
return string.Format("_queryHandler is {0}; _cacheQueryHandler is {1}", _queryHandler,
_cacheQueryHandler);
}
}
static void Main(string[] args)
{
var builder = new ContainerBuilder();
// Register the dependency
builder.RegisterType<QueryHandler>().As<IQueryHandler>();
// Register the decorator of the dependency
builder.RegisterType<CacheQueryHandler>().Keyed<IQueryHandler>("cache");
// Register the service implementation
builder.RegisterType<Service>().AsSelf();
// Register the interface of the service
builder.Register(c =>
{
var ctor = typeof (Service).GetConstructors()[0];
var parameters =
ctor.GetParameters()
.Where(p => p.Name.StartsWith("cache"))
.Select(p => new NamedParameter(p.Name, c.ResolveKeyed("cache", p.ParameterType)));
return c.Resolve<Service>(parameters);
}).As<IService>();
using (var container = builder.Build())
{
var service = container.Resolve<IService>();
Console.WriteLine(service.ToString());
Console.ReadKey();
}
}
}
Update:
Basically you need to:
1. Think up a general convention. Prefix "cache" of ctor parameter name in your case.
2. Register your dependencies as usual.
3. Register your decorators, so they don't overwrite your original dependencies and you can easily resolve them basing on your convention. e.g. Keyed, Named, via Attribute, etc.
4. Register you actual implementation of class that uses decorators
5. Register your interface that describes the class via lambda expression that has all magic inside.
Note: I provided just a simple and working example. It's on you to make it nice, easy to use and fast e.g. make it as an extension, generic, cache reflection results etc. It's not difficult anyway.
Thanks.

How to use Dependency Injection with Static Methods?

Imagine there is a Customer class with an instance Load() method.
When the Load() method is called, it retrieves order details by e.g.
var orders = Order.GetAll(customerId, ...);
GetAll() is a static method of the Order class and the input parameters are fields defined in the Customer class.
As you can see, Order is a dependency of the Customer class, however, I can't just create an IOrder and inject it there as interfaces can't have static methods.
Therefore, the question is how could I introduce dependency injection in this example?
I don't want to make GetAll() an instance method since it's a static method and need to keep it that way.
For example, I have used utility classes in my design, most of which just contain static methods.
If you must keep the static method, I would wrap the static calls in a Repository object.
Like this:
interface IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ..);
}
class OrderRepository : IOrderRepository {
IEnumerable<IOrder> GetAll(customerId, ...)
{
Order.GetAll(customerId,...); // The original static call.
}
}
Now you inject this repository into your Customer class.
(I'm assuming you're doing this so you can inject fake IOrders at runtime for testing purposes. I should say that in general, static methods are a serious obstacle to testing.)
Seeing as your aggregate root for fetching orders is your customer model I would strongly advise you create a customer repository and inject that to whatever service requires it.
Here is an example:
public class CustomerService
{
private readonly ICustomerRepository _customerRepository;
public CustomerService(ICustomerRepository customerRepository)
{
if (customerRepository == null)
{
throw new ArgumentNullException("customerRepository");
}
_customerRepository = customerRepository;
}
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
return _customerRepository.GetOrdersForCustomerId(customerId);
}
}
public interface ICustomerRepository
{
IEnumerable<IOrder> GetOrdersForCustomerId(int customerId);
}
class CustomerRepository : ICustomerRepository
{
public IEnumerable<IOrder> GetOrdersForCustomerId(int customerId)
{
throw new NotImplementedException();
}
}
Function Pointer Injection
TLDR:
Inject a function pointer into the Customer class. The value of this function pointer can be Order.GetAll in production, and MockOrder.GetAll in tests.
EXAMPLE:
The dependency (problematic static function we depend on):
class Order {
static func GetAll() -> [Order] {
var orders = ... // Load from production source
return orders
}
}
Our dependent class (depends on static function):
class Customer {
func Init(getAllOrdersFunction) { // Arg is a func pointer
self.getAllOrdersFunction = getAllOrdersFunction
}
func Load() {
var orders = self.getAllOrdersFunction()
// Do stuff...
}
}
Production client class (performs the dependency injection):
class BusinessLogicManager {
func DoBusinessLogic() {
var customer = Customer(Order.GetAll) // Prod func injected here
customer.Load()
// Do stuff...
}
}
Testing client class (how unit test can inject a fake dependency):
class CustomerUnitTests {
static func GetFakeOrders() {
var orders = ... // Hardcoded test data
return orders
}
func TestLoad() {
var customer = Customer(CustomerUnitTests.GetFakeOrders) // Fake func injected here
customer.Load()
// Verify results given known behavior of GetFakeOrders
}
}
DISCUSSION:
How you actually inject the "function pointer" will depend on the syntax and features available in your language. Here I'm just talking about the general concept.
This isn't exactly a pretty solution. It would probably be easier if you can change GetAll to be an instance method (perhaps by introducing an OrdersLoader object, or by using Paul Phillips' answer). But if you really want to keep it as a static function, then this solution will work.

Resources