How to initialize class static property once - class

Here is my code where I am mocking the User object by initializing array or users and then defining the operations on it.
import IUser = require("../interfaces/IUser");
export class User implements IUser {
private static users: User[] = [];
constructor(public name: string) {
this.name = name;
User.users.push(this);
}
private static init()
{
//creating some users
new User(/****/);
new User(/****/);
...
}
public static findOne(login: any, next:Function) {
//finding user in users array
}
public static doSomethingelse(login: any, next:Function) {
//doSomethingelse with users array
}
}
Basically before doing findOne(..) doSomethingelse() I need users to be created and I do not want to do something like:
public static findOne(login: any, next:Function) {
User.init();
//finding user in users array
}
public static doSomethingelse(login: any, next:Function) {
User.init();
//doSomethingelse with users array
}
Is there better way?

You could do something like this:
export class User implements IUser {
private static users = User.initUsers();
constructor(public name: string) {
this.name = name;
User.users.push(this);
}
private static initUsers()
{
User.users = [];
new User(...);
return User.users;
}
}

Related

With LightInject, how can I pass arguments to child dependencies without registering a bunch of factories?

In the code below, I am trying to inject a ViewModel into a View, while the ViewModel requires a Model to wrap and another service that is in the container. The Model is not registered as it is not really a "service".
How do I:
a) not have to provide the IService instance as an argument (let the container resolve it),
b) not have to register a factory for my ViewModels (there will be many)
So what I'm really asking the container to do is treat my Model (that I pass as an argument) as if it were a registered "service" for the duration of this call to GetInstance.
If this is not possible with LightInject, are there any containers out there that have something like this?
public static class Program
{
public static void Main()
{
var container = new LightInject.ServiceContainer();
var service = new Service1();
container.RegisterInstance<IService>(service);
// Have to register the factory
container.Register<IService, PersonModel, PersonViewModel>(
(f, s, p) => new PersonViewModel(s, p));
container.Register<View>();
var person = new PersonModel(); // this is contextual -- not a service.
object view = CreateView(container, typeof(View), service, person);
// ultimate desired code:
//var view = container.GetInstance(typeof(View), new object[] { person });
}
private static object CreateView(ServiceContainer container, Type viewType, IService service, object model)
{
var ctor = viewType.GetConstructors()[0];
var parameters = new List<object>();
foreach (var param in ctor.GetParameters())
{
var attr = param.GetCustomAttributes(typeof(ModelAttribute), false).FirstOrDefault();
if (model != null && attr != null)
{
parameters.Add(model);
}
else
{
parameters.Add(container.GetInstance(param.ParameterType, new object[] { service, model }));
}
}
return Activator.CreateInstance(viewType, parameters.ToArray());
}
}
public interface IService
{
}
public class Service1 : IService
{
}
public class PersonModel
{
}
public class PersonViewModel
{
public PersonModel PersonModel { get; set; }
public PersonViewModel(IService service, [Model] PersonModel person)
{
PersonModel = person;
}
}
public class View
{
public PersonViewModel PersonViewModel { get; set; }
public View(PersonViewModel vm)
{
PersonViewModel = vm;
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public class ModelAttribute : Attribute
{
}
I have solved the issues with a combination of techniques...
a) use a Scope and register the ViewModel and View with PerScopeLifetime.
b) use a "ModelTracker" registered with a factory to allow an instance not created by the container to be injected (since models will be created by client code or a DbContext).
This combination also allows me to not register a factory for every ViewModel type -- but instead use the built-in mass registration functions (like RegisterAssembly).
public static class Program
{
public static void Main()
{
var container = new LightInject.ServiceContainer();
container.RegisterInstance<IService>(new Service1());
container.Register<View>(new PerScopeLifetime());
container.Register<PersonViewModel>(new PerScopeLifetime());
container.Register<ModelTracker>(new PerScopeLifetime());
container.Register<PersonModel>((f) => (PersonModel)f.GetInstance<ModelTracker>().Instance);
using (var scope = container.BeginScope())
{
var tracker = scope.GetInstance<ModelTracker>();
tracker.Instance = new PersonModel() { Name = "person1" };
var view = scope.GetInstance<View>();
}
}
}
public class ModelTracker
{
public object Instance { get; set; }
}
public class PersonModel
{
public string Name { get; set; }
}
public class PersonViewModel
{
private readonly IService service;
private readonly PersonModel person;
public PersonViewModel(IService service, PersonModel person)
{
this.service = service;
this.person = person;
}
}
public class View
{
public PersonViewModel PersonViewModel { get; set; }
public View(PersonViewModel vm)
{
PersonViewModel = vm;
}
}
public interface IService { }
public class Service1 : IService { }

Access members of inner class from the outer class - TypeScript

I'm trying to group some members of a class in TypeScript. Consider the following class:
export class MyClass {
private member: string = 'foo';
public getFoo(): string {
this._doSomething();
return this.member;
}
// Helper
_doSomething() { console.log(this.member); }
}
What I basically want to do is to wrap _doSomething with a namespace (let's call the namespace helpers) so inside getFoo() I can call this.helpers._doSomething().
Of course, this is super easy to do in Javascript since we can define an object as a member and define the helper functions inside the object.
In TypeScript, I almost got the same effect through class expressions:
export class MyClass {
private member: string = 'foo';
public getFoo(): string {
this.helpers._doSomething();
return this.member;
}
private helpers = class {
// To have access to the parent's members
constructor(private parent: MyClass) { }
public _doSomething() { console.log(this.parent.member); }
};
}
The only problem is that the MyClass can't have access to helpers class members.
How do I get access to the inner class members from the outer class?
Is there a better way to achieve the namespace helpers?
Any help would be appreciated.
Updated
Using the accepted answer achieves the goal:
export class MyClass {
private member: string = 'foo';
public getFoo(): string {
this.helpers._doSomething();
return this.member;
}
private helpers = new (class {
// To have access to the parent's members
constructor(private parent: MyClass) { }
public _doSomething() { console.log(this.parent.member); }
})(this);
}
You just defined the class, to have access to the non-static members you have to new it up. You can do this inline like so :
export class MyClass {
private member: string = 'foo';
public getFoo(): string {
this.helpers._doSomething();
return this.member;
}
private helpers = new (class {
// To have access to the parent's members
constructor(private parent: MyClass) { }
public _doSomething() { console.log(this.parent.member); }
})(this);
}
Or if you want to have multiple instances of the helper class you can new it up as needed:
public getFoo(): string {
let h = new this.helpers(this);
let h1 = new this.helpers(this);
h._doSomething();
h1._doSomething();
return this.member;
}
You can achieve a similar effect by using the merging of a class and a namespace, the problem is you will not have access to private members, while your solution requires this:
export class MyClass {
// Must be public for access from helper
public member: string = 'foo';
public getFoo(): string {
let h = new MyClass.helpers(this);
h._doSomething();
return this.member;
}
}
export namespace MyClass {
// must be exported to be accesible from the class
export class helpers {
// To have access to the parent's members
constructor(private parent: MyClass) { }
public _doSomething() { console.log(this.parent.member); }
}
}

Specific behaviour on validate() method on Play! Framework

I am looking to have specific behaviour on my validate() method (like the one I can have with the groups annotation) either if it's called on
Form<User> loginForm = form(User.class, User.Login.class).bindFromRequest();`
or on
Form<User> registerForm = form(User.class, User.Register.class).bindFromRequest();
User Model :
#Entity
public class User extends Model {
public interface Register {}
public interface Login{}
#Required(groups = {Register.class, Login.class})
public String username;
#Required(groups = {Register.class, Login.class})
public String password;
public List<ValidationError> validate() {
... // Here I would like to distinguish User.Login.class from User.Register.class
}
}
Application Controller
public static Result loginSubmit(){
Form<User> loginForm = form(User.class, User.Login.class).bindFromRequest();
}
public static Result registerSubmit(){
Form<User> registerForm = form(User.class, User.Register.class).bindFromRequest();
}
The group parameter isn't passed to the validate() method so I don't think that's possible. It's not as convenient but you could just call validate (or some other validation method) yourself.
User Model:
public class User extends Model
{
public List<ValidationError> validate(Class group) {
if (group == Login.class) {
...
} else if (group == Register.class) {
...
}
}
}
Controller:
public static Result loginSubmit(){
Form<User> loginForm = form(User.class, User.Login.class).bindFromRequest();
if (!loginForm.hasErrors()) {
User user = loginForm.get();
List<ValidationError> errors = user.validate(User.Login.class);
...
}
}

POJO information lost during RPC call (GWT)

I am having issues with RPC calls and GWT. Essentially, I have a Person class (common code between client and server) that is created in the client side web code, sent to the server code via an RPC call, and then saved to a DB (OrientDB). I have verified that the following work:
RPC call - I am able to send info to the server and retrieve info from the server
save to DB - have verified that a Person object is saved to the DB
Where I am having issues is the transfer of the POJO from the client to the server. I have verified that the POJO's properties are intact right before it is sent to the server, however, the object passed to the server contains null values for all properties. Essentially, the class is transferred but the information is not. It then saves to the DB, but obviously without any relevant information contained within it.
I will copy what I feel is relevant below, please let me know what else I can provide to make this problem easier to identify. Note these are still in a testing state, so mind the comments :)
Any idea why my POJO's information is being lost in translation?
Person object, followed by the abstract class it inherits from:
public class Person extends org.matesweb.shared.AbsPerson implements Serializable
{
#Id
private String id; // DON'T CREATE GETTER/SETTER FOR IT TO PREVENT THE CHANGING BY THE USER APPLICATION,
// UNLESS IT'S NEEDED
//sets new user details
public void setPerson(String fIrstName, String mIdInit, String lAstName, String email, String password)
{
firstName = fIrstName;
middleInitial = mIdInit;
lastName = lAstName;
}
/*getter and setter methods - required for every
* field due to restrictions imposed by OrientDB*/
public Object getId()
{
String tmp;
tmp = id.toString();
return tmp;
}
//end class
}
public class AbsPerson implements Serializable
{
String firstName;
String middleInitial;
String lastName;
// public sys.Login login;
public org.matesweb.shared.Group[] groups;
private org.matesweb.shared.Purchase[] purchases;
/*this method adds a new purchase to the purchases variable*/
/* public void addPurchase(float price, String description)
{
people.Purchase newPurchase = new people.Purchase(login, price, description);
}
*/
/*adds a person to a group by comparing the passed in group ID and PWD*/
public void addGroup(String groupID, String groupPWD)
{
//compare group ID with group PWD to add a user to the group
}
/*getter and setter methods - required for every
* field due to restrictions imposed by OrientDB*/
public String getFirstName()
{
return firstName;
}
public void setFirstName(String name)
{
firstName = name;
}
public String getMiddleInitial()
{
return middleInitial;
}
public void setMiddleInitial(String midInit)
{
middleInitial = midInit;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String ln)
{
lastName = ln;
}
/*
public sys.Login getLogin()
{
return login;
}
public void setLogin(sys.Login log)
{
login = log;
}
*/
public org.matesweb.shared.Group[] getGroups()
{
return groups;
}
public void setGroups(org.matesweb.shared.Group[] gro)
{
groups = gro;
}
public org.matesweb.shared.Purchase[] getPurchases()
{
return purchases;
}
public void setPurchases(org.matesweb.shared.Purchase[] purch)
{
purchases = purch;
}
}
Service
package org.matesweb.client;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import org.matesweb.shared.Person;
#RemoteServiceRelativePath("peopleService")
public interface PeopleService extends RemoteService {
//test services
String stringTest(String outgoingString);
Person getPerson(String persId);
//production services
String savePerson(Person p);
}
ServiceAsync
import com.google.gwt.user.client.rpc.AsyncCallback;
import org.matesweb.shared.Person;
public interface PeopleServiceAsync
{
//tests
void stringTest(String outgoingString, AsyncCallback<String> incomingString);
void getPerson(String persId, AsyncCallback<Person> retPerson);
//production services
void savePerson(Person p , AsyncCallback<String> st);
}
ServiceImpl call for this particular method:
//production calls
#Override
public String savePerson(Person p) {
String st = ioObj.saveObj(p);
if(st.equals("Success")){
return "Your information has been saved successfully!";
} else{
return "Something has gone wrong on our end... Sorry! Error:<br /> " + st;
}
}
and finally, the call itself
private static void savePerson(Person p)
{
// Initialize the service proxy.
if (peopleSvc == null) {
peopleSvc = GWT.create(PeopleService.class);
}
//resets status
st="";
// Set up the callback object.
AsyncCallback<String> callback = new AsyncCallback<String>() {
#Override
public void onFailure(Throwable caught) {
st = caught.getMessage();
Label stLabel= new Label(st);
personTable.setWidget(3,1,stLabel);
}
#Override
public void onSuccess(String result) {
st = result;
HTML stLabel= new HTML(st);
joinPanel.add(stLabel);
}
};
// Make the call to the people service.
peopleSvc.savePerson(p, callback);
}
I was able to fix this issue by implementing GWT's IsSerializable interface. I also removed the Serializable interface from the Person class and let it inherit IsSerializable from the abstract class it inherits from.

Struts 2 ModelDriven Action suporting both a list and individual items

I have inherited some struts2 REST-plugin based code, and the following construct puzzles me:
#Namespace("/merchants/{id}")
public class MerchantAction extends ActionSupport implements ModelDriven<Object> {
private Merchant merchant = new Merchant(); // A Model
private Iterable<Merchant> merchants; // A list of models
....
public HttpHeaders index() {
merchants = merchantService.findAllMerchants();
return new DefaultHttpHeaders("index");
}
#Override
public Object getModel() {
return (merchant != null ? merchant : merchants);
}
public void setId(String id) {
merchant = merchantService.findMerchant(id));
}
In other words, it seems to be toggling between returning a list and returning an individual item in the getModel() call. Is this kosher ? Looks a bit strange to me
I've considered your approach, but finally gave it up. IMO, it lost the advantage of strong typed action.
My solution is, creating a ViewModel for each action. In the view models, there can be the single model, the list of the model, and other items for pages usage, such as items for drop down list or radio buttons.
So the UserViewModel is like:
public class UserViewModel implements IViewModel<User> {
private User model;
private List<User> list;
public void setModel(User user) {
this.model = user;
}
public User getModel() {
return model;
}
public void setList(List<User> list) {
this.list = list;
}
public List<User> getList() {
return list;
}
}
And the actions are like:
public class UserController implements ModelDriven<UserViewModel> {
private int id;
private UserViewModel model = new UserViewModel();
public String index() {
return "success";
}
public String show() {
return "success";
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
#Override
public UserViewModel getModel() {
return model;
}
}
But in this way, I still lose the shortcut way in jsp files. I should write long model.userName instead of short userName.
I'm still finding the best solution of it.