Calling CreateScope() or BeginScope() Manually inside azure function - .net-core

I am writing an eventhub triggered azure function that receives a list of objects in each event from eventhub. I want to instantiate an object of some type for each object of the list that I receive. If I register that type as scoped by calling builder.Services.AddScoped I will have new instance for each eventhub event(for each function call). I want to control the instance creation. SO I want to have something like bellow inside my function.
using (var scope = builder.Services.BuildServiceProvider().CreateScope())
{
// scope.ServiceProvider.GetService(type)
}
In that way for each object in the list inside each event hub event I can have new Instance of some type.

I found a solution of my problem. Inside Configure method of Startup we can register ServiceProvider like bellow
builder.Services.AddScoped<IEventContext, EventContext>();
builder.Services.AddSingleton<ServiceProvider>(builder.Services.BuildServiceProvider());
Then we can set ServiceProvider as a dependency in the function app class and we can call CreateScope() directly like bellow inside function
using (var scope = this._serviceProvider.CreateScope())
{
var ctx = scope.ServiceProvider.GetService<IEventContext>();
var ctx2 = scope.ServiceProvider.GetService<IEventContext>();
this._logger.LogInformation(ctx.GetHashCode().ToString()); //same
this._logger.LogInformation(ctx2.GetHashCode().ToString()); //same
}

Related

Action requires multiple controllers to execute

I have a UserController that has a Destroy function. It is a rather complex function because it demands to destroy all user's data. I have another action, from the Admin panel that deletes all data from a specific set of users.
Since I don't want to replicate the code from the UserController, I would like to call the Destroy function from UserController for each User to destroy its data.
How should I proceed?
Thanks in advance.
Why not move this functionality to a common class method which can be accessed from both the controllers as needed ?
public class UserManager
{
public void Destroy(List<int> userIdsToDestroy)
{
foreach(var userId in userIdsToDestroy)
{
//Execute code to destroy
}
}
}
and from your action methods, you can call it like
var mgr = new UserManager();
var badUsers = new List<int> { 1,2,3};
mgr.Destroy(badUsers);
Update the badUsers variable value as needed based on from where you are calling it.
Shared functionality like this would ideally be in a business layer, and both controllers would call that code. If it's a little app, you could just create a separate folder structure for shared code. Larger projects would have a business layer dll.
Why not make the Destroy() method as a Non-Action method then like
[Non-Action]
public void Destroy(User user)
{
// code goes here
}
You can as well make this Destroy() function as part of your business layer logic instead of handling this in controller. In that case, you call it from anywhere.
If you want it to be #controller, you can as well consider usig [ChildActionOnly] action filter attribute.

AngularJS Insert in Web Api is null

I'm trying to put together my first CRUD app using AngularJS and Asp.Net Web Api. I have setup the controller with a newMember object:
$scope.newMember = {};
And then call the insert in the factory method as:
dataService.insertMember($scope.newMember);
This calls the method in the dataService:
var _insertMember = function(member) {
return $http.post("/api/clubmembers/", member);
};
which fires the Web Api Post method
public HttpResponseMessage Post([FromBody]PersonViewModel member)
{
//if (_repo.AddClubMember(member) && _repo.Save())
if (_repo.AddClubMember(member) && _repo.Save())
{
return Request.CreateResponse(HttpStatusCode.Created, member);
}
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
I have checked the data in the Angular part of the app and the correct data is passed via $scope.newMember, but when it reaches the Web Api Post method the member parameter is always Null.
If I modify the controller method to the following it passes the data to the Post method as expected:
var testData2 = {
FirstName: $scope.newMember.FirstName,
LastName: $scope.newMember.LastName
};
var a = 1;
dataService.insertMember(testData2);
Is it possible to pass $scope.newMember as the parameter or do I have to fill in the details as of the amended code?
Thanks
Mark
Check your code carefully, I would say (based on your experience described in the question) there will be some typo.
Call with explicit {} - empty object
If you will call your service like this:
dataService.insertMember({}); // just created empty object
you will get instantiated object on your API Post method PersonViewModel member
Call with explicit null or undefined
but in case, that you will call one of these
dataService.insertMember(null);
dataService.insertMember(undefined);
the API Post method will be provided with NULL.
typo (incorrect property name), i.e. undefined
And what that means? that you most likely, somewhere in the call chain used something like this
$scope.newMember ...
...
dataService.insertMember($scope.newMemberXXX);
where newMemberXXX represents any undefined property, resulting in undefined to be passed
If you add FirstName and LastName properties to newMember it should work fine:
$scope.newMember = {};
$scope.newMember.FirstName = "First Name";
$scope.newMember.LastName = "Last Name";
dataService.insertMember($scope.newMember);
Thing is, $scope.newMember has to match the properties and structure of PersonViewModel for the Web Api to be able to match the two types.
Let us know if this works.

flex netconnect ( Property onTest not found on flash.net.NetConnection and there is no default value )

Having this code:
nc.call("test", new Responder(onCallSuccess,onCallFailed), "user1");
and
public function onTest(id:String):void {
Alert.show("test called from server");
}
Results in:
`ReferenceError: Error #1069: Property onTest not found on flash.net.NetConnection and there is no default value`.
How could I fix this?
Ive tried a lot of different approaches, it seems that the data is send from server application correctly but flex cannot "eat it"
You need to add nc.client = this, so the server knows where to call methods.
As I understand, onTest is callback method. Callback methods must be contained in client property of NetConnection instance. The default value for client is NetConnection instance itselft. That's why onTest is trying to be called, but it does not exist. You have 2 possible solutions here:
1.Extend NetConnection class with your custom one and define onTest method there. And use your custom class instead.
class MyNC extends NetConnection
{
public function onTest(id:String) {...}
...
}
2.Create class, which will be client for NetConnection and define onTest there.
class Client
{
public function onTest(id:String) {...}
}
...
var nc:NetConnection = new NetConnection();
nc.client = new Client();

Multiple asynchronous calls to populate an object

I'm developing a Flex application and am having some trouble working with asynchronous calls. This is what I would like to be able do:
[Bindable] var fooTypes : ArrayCollection();
for each (var fooType : FooType in getFooTypes()) {
fooType.fooCount = getFooCountForType(fooType);
itemTypes.addItem(fooType);
}
The issue I'm running into is that both getFooTypes and getFooCountForType are asynchronous calls to a web service. I understand how to populate fooTypes by setting a Responder and using ResultEvent, but how can I call another service using the result? Are there any suggestions/patterns/frameworks for handling this?
If possible, I Strongly recommed re-working your remote services to return all the data you need in one swoop.
But, if you do not feel that is possible or practical for whatever reason, I would recommend doing some type of remote call chaining.
Add all the "remote calls" you want to make in array. Call the first one. In the result handler process the results and then pop the next one and call it.
I'm a bit unclear from your code sample when you are calling the remote call, but I assume it part of the getFooCountForType method. Conceptually I would do something like this. Define the array of calls to make:
public var callsToMake : Array = new Array();
cache the currently in process fooType:
public var fooType : FooType;
Do your loop and store the results:
for each (var fooType : FooType in getFooTypes()) {
callsToMake.push(fooType);
// based on your code sample I'm unclear if adding the fooTypes to itemTypes is best done here or in the result handler
itemTypes.addItem(fooType);
}
Then call the remote handler and save the foo you're processing:
fooType = callsToMake.pop();
getFooCountForType(fooTypeToProcess);
In the result handler do something like this:
// process results, possibly by setting
fooType.fooCount = results.someResult;
and call the remote method again:
fooType = callsToMake.pop();
getFooCountForType(fooTypeToProcess);

Flex: How to use flashvars from different classes

I am just learning actionscript, so come across the problem
In my application I often call to different web services, and because I don't want to hardcode urls to them in my code, I am passing urls to the services as flashvars.
Currently I am doing it this way:
public var siteUrl:String;
public var gameId:String;
public function main():void
{
siteUrl = Application.application.parameters.siteurl;
gameId = Application.application.parameters.gameid;
Where main is a function, which is called on application's creation complete event.
This way I can call both variables from main file of the application but I want to access them from other files. (other as classes)
So is there a way to create class with constants and init values there with flashvars so I can use them everywhere (after importing of course)
The parameters are just stored in that Application.application.parameters object, and that's static. There's no reason you couldn't access that from other classes in your code.
If you want to write a class that wraps the parameters (maybe validates them or something) you could do that fairly easily. You can use a for each loop to loop over all the parameters. Something like:
var params:Object = Application.application.parameters
for(var name:String in params) {
var value:String = params[name] as String;
/* do something with the param */
}
If you want your class to actually verify things then it could just check for each parameter it expects and store it in a local variable.
It really just depends on your own preferences. Some people are fine with accessing the parameters object when they need it. Some people like having the extra code-completion by having a config class that actually defines all the expected config variables.
Update in response to comment:
Instead of having one module declare the variable and have other modules have to depend on that one to access the property it would be cleaner to have a single config module that everything that needs it would all use.
You could use a static class or singleton or some IoC stuff. Just for simplicity I'll show you a way you can do it with a static class.
class MyConfig {
private static var _infoService:String;
private static var _someOtherParam:int;
public static function get infoService():String { return _infoService; }
public static function get someOtherParam():int { return _someOtherParam; }
public static function initParams():Void {
var params:Object = Application.application.parameters;
_infoService = params.infoservice;
// just assuming you have a method to convert here. don't remember the
// code off the top of my head
_someOtherParam = convertToInt(params.someOtherParam);
}
}
Make sure when your app initializes it calls MyConfig.initParams(). You can have that method actually validate that it gets everything it expects and throw exceptions (or return an error) if there's a failure if you want.
Then wherever you need to use that config within your code you just import your config class and access the param. So getting infoService would just be:
var infoService:String = MyConfig.infoService;
Personally I wouldn't use a static class, but it was the easiest to show.

Resources