Azure function: This method cannot be called during the application's pre-start initialization phase - unity-container

I've created an Azure function and have created a class which implements the IExtensionConfigProvider interface with the Initialize method to do some "bootstrapping" on "start up". Included in the bootstapping is some Unity registration where I use the BuildManager.GetReferencedAssemblies() to complete convention registrations.
However I'm getting This method cannot be called during the application's pre-start initialization phase error when BuildManager.GetReferencedAssemblies() is called. I've even put this method in the actual function code (so not "start up") and still get this error. Any ideas?

It sounds like you're trying to do something that's not supported. IExtensionConfigProvider.Initialize() is a very protected context and you can't really control when it runs - it should just be used to register binding rules. Azure Functions does not yet have dependency injection support.
If you have code that you want to run early, you could put it in a static constructor.
If you want more control, you could switch to using the underlying WebJobs SDK (which allows you to own the main function). Functions is layered on top of WebJobs SDK.

Related

Since ILogger<T> is a singleton, how different threads can use BeginScope() without affecting others?

This is related to this question. Context: .Net Core 3.1, using Microsoft.Extensions.Logging
Loggers are singletons in the application's IHost. If I inject (DI) an ILogger<T> into my class or method, the injected object is the same instance other classes or methods receive if they ask for ILogger<T>. This poses the question of what happens when I use logger.BeginScope($"Processing {transactionId}") in one thread. What happens with the other threads? Do they change the logging scope as well? Do logging scopes get mixed up? If they don't: how does that work, being their loggers the same object? If they do mix scopes, how can I make two threads use different logging scopes for a given ILogger<T> type?
This depends on the logger implementation, but typically they're implemented using a type of stack held within an AsyncLocal.
A call to BeginScope will put a new item onto that stack, and the adjoining Dispose will pop it off of that stack.
When the logger is invoked via LogInformation or otherwise, the data of the current stack object will be copied to write it to the console or whatever output that logger instance is configured to do.
The AsyncLocal is what gives the framework the ability to store information across threads and tasks.
For reference, check out the Microsoft.Extensions.Logging.Console source code:
ConsoleLogger.cs#L67
LoggerExternalScopeProvider.cs#L14

Call remote test library constructor as keyword from Robot Framework

Is it possible to call Test Library constructor from Robot Framework?
Using Remote library interface (NRobot.Server) to connect from RF to Test Library (implemented in C#).
Currently its exposing all public methods implemented under Test Library except constructors.
There are multiple Test Libraries in our project where some functionality implemented as part of constructors.
Hence need a way to call constructor as a test step to execute certain functionality whenever required.
If not possible then may need to move functionality from constructors to new public methods. But want to avoid that if possible.
Thanks in advance...
In short - no.
When calling a remote library, you're actually just the client in an XML-RPC comm protocol; it is the server's responsibility to have the library instantiated, so it (the very same library) can process your instructions and act as needed. Thus normally the library is already instantiated when you call it from your RF code - too late to invoke its constructor.
Naturally, this can be implemented differently - for the remote library server to instantiate the target library on a (special) call, and thus you'll to be able to provide constructor arguments, but that is library design/code change required in it.
This is in contrast of using local libraries, where they are instantiated in your local interpreter, on their import.

Preloading variables in RoleEntryPoint OnStart

I need to download some tables from the database, and create static list classes with the information. I can do this in owin startup, or RoleEntryPoint onStart.
I tried to preload the lists in RoleEntryPoint onStart, however, these classes doesnt seem to be available in the runtime, instead they got created again.
If I preload them in Owin Startup, everything works as it should.
However, it takes about 10 seconds for me to preload these lists, and while owin startup is executing, the Onstart already had been executed and therefore the web role becomes available for accepting requests. I dont want this though. I dont want the web role to switch to ready state until all of the lists are preloaded.
it seems like any instances that are created in RoleEntryPoint arent available in the webrole runtime itself.
Is there any way to achieve preloading instances in OnStart and having being able to use them in the runtime?
RoleEntryPoint is the best way to achieve your requirement.
Define static List variables with singleton pattern in the WebRole.cs.
Implement async repository or private methods to fill them. You do not have to populate your static lists on app startup. According to the singleton pattern, they will get filled on first request.
I use the same approach in my static repository instance initialization of WCF service startup process.
Good luck

How do I get a service to start from global.asax without having to invoke it?

I have a simple app where I use global.asax to map a serviceroute to a wcf service through a custom servicehostfactory in Application_Start. The constructor of that service does some initial processing to set up the service which takes a bit of time.
I need this constructor to fire when its serviceroute is added automatically. I tried creating a clientchannel from global.asax and making a dummy call to spin up the service, but discovered the service isn't up yet -- it seems application_start has to return?
So how do I get the constructor of the service to fire when first mapped through global.asax without having to manually hit the service? Unfortunately AppFabric isn't an option for us, so I can't just use it's built-in autostart..
UPDATE
I was asked for a bit more detail;
This is like a routing management service. So I have Service1 -- it gets added as a serviceroute in global.asax. Now I have http://localhost/Service1
Inside Service1 I have a method called 'addServiceRoute'. When called, it also registers a route for Service2. Now I have http://localhost/Service1/Service2.
My initial solution from global.asax was to build a channelfactory to http://localhost/service1 but that wouldn't work. Service1 wasn't up yet and wouldn't come up till Application_Start returned (Still not sure why?). So then I thought I'd cheat and move that initial addserviceroute call to the constructor of service1. Also didn't work.
It was mentioned that this shouldnt be in the constructor -- i agree, this is just testing code.
A singleton was also mentioned, which might be ok, but I intend to have more than one instance of Service1 on a machine (in the same app pool) so I don't think that'll work?
** UPDATE #2 **
I was asked for sample code.. here it is from global.asax (trimmed a bit for brevity).. So http://localhost/Test DOES come up.. But if I have to use appfabric to warm up Test and get its constructor to fire, then don't I need Test.svc or something? How do I get appfabric to even see this service exists?
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Ignore("{resource}.axd/{*pathInfo}");
RouteTable.Routes.Add(
new ServiceRoute("Test", new MyServiceHostFactory(ITestService, BindingType.BasicHttpBinding, true), TestService));
}
What you describe requires singleton service (something you should avoid) because normally each call or session gets a new instance = a new call to constructor. In self hosted WCF service you can instantiate singleton service instance and pass it to ServiceHost constructor. In case of IIS hosted service used together with ServiceRoute you can try to create your own class derived from ServiceHostFactory and pass created service instance as a parameter to its constructor. In this factory class implement CreateServiceHost method and pass that existing service instance into ServiceHost constructor. To make this work your service class must still be handled as singleton through service behavior.
Btw. constructor should not do any time consuming operation. Constructor is for constructing object not for initializing infrastructure. Using constructor for such initialization is bad practice in the first place.
AppFabric autostart is what I would recommend - even though you say you cannot use it - this is the problem it was meant to solve (warming up your service).
As an alternative before AppFabric existed, you would have to use a scheduled task (a.k.a cron job) with an executable that calls into the service you want initialized. The way AppFabric autostart works is by using named pipes (net.pipe) to trigger the warm up - but it just does this exact thing when the service is recycled. The difference between the scheduled task approach and the AppFabric autostart is that the scheduled task doesn't know when your application pool has been recycled - you would need to poll your service periodically to keep it warm.
Alternatively you could consider hosting your WCF application outside of IIS via self-hosting. This would avoid the warm-up issue, but you wouldn't achieve many of the benefits of the IIS hosted container. See HttpSelfHostServer in the new MVC Web API or review using a standard ServiceHost.

What is the most appropriate place for placing (startup) initialization code in a Restlet application?

Where can I embed startup initialization code in a Restlet web application, without using a ServletContextListener?
I wish to have transparent deployment of my Restlet to a web server like JBoss/Tomcat and would like to get rid of the initialization logic in the Listener - so as to be able to conveniently deploy it outside of a web server, if the need be - definitely not for heavy production use, but it's valuable nevertheless.
Would inserting it into org.restlet.Component's constructor ensure that it'll only execute once? Is that the right place to put it?
public class MyComponent extends org.restlet.Component
{
public MyComponent() //constructor
{
//insert initialization code here that should run ONLY ONCE?
this.getDefaultHost().attach(new MyApplication()); // MyApplication extends org.restlet.Application
}
}
I went through the docs and also looked at a similar post: RESTlet startup initialization deprecated? but I'm still not sure if it's the right way. I would like to remove the dependency on the Listener if at all possible.
Using the constructor of the Component is a good place for initialization processing and you can be sure that such processing are only executed once.
You can notice that the method start / stop of the component can also be used in your case. Don't forget to call the super method in them. These methods are called when you start / stop your component that is commonly done once...
Hope it helps you.
Thierry

Resources