How does versioning work with Flex remote objects and AMF? - apache-flex

Suppose I use the [RemoteClass] tag to endow a custom Flex class with serialization intelligence.
What happens when I need to change my object (add a new field, remove a field, rename a field, etc)?
Is there a design pattern for handling this in an elegant way?

Your best bet is to do code generation against your backend classes to generation ActionScript counterparts for them. If you generate a base class with all of your object properties and then create a subclass for it which is never modified, you can still add custom code while regenerating only the parts of your class that change. Example:
java:
public class User {
public Long id;
public String firstName;
public String lastName;
}
as3:
public class UserBase {
public var id : Number;
public var firstName : String;
public var lastName : String;
}
[Bindable] [RemoteClass(...)]
public class User extends UserBase {
public function getFullName() : String {
return firstName + " " + lastName;
}
}
Check out the Granite Data Services project for Java -> AS3 code generation.
http://www.graniteds.org

Adding or removing generally works.
You'll get runtime warnings in your trace about properties either being missing or not found, but any data that is transferred and has a place to go will still get there. You need to keep this in mind while developing as not all your fields might have valid data.
Changing types, doesn't work so well and will often result in run time exceptions.
I like to use explicit data transfer objects and not to persist my actual data model that's used throughout the app. Then your translation from DTO->Model can take version differences into account.

Related

how to do Shell Navigation with complex objects in .net MAUI or Xamarin Forms?

Recently I've started using shell and I noticed an improvement in page transitioning and a bug I was facing using NavigationPage was fixed just by replacing it with shell.
So I was excited to use it.
However soon after I realized I can't send objects from page to page through shell like I could using a constructer of a page. I searched a bit and now know that shell passes strings only. I turned the object into JSON but then faced an exception due to long URI length.
Honestly, I am disappointed. I thought something this important would be implemented in shell... but In any case, how do you guys work around this?
For Maui.
See (Xamarin) Process navigation data using a single method.
Also mentioned in maui issue. Adapting the Maui invocation there:
await Shell.Current.GoToAsync("//myAwesomeUri",
new Dictionary { {"data", new MyData(...)} });
This uses IQueryAttributable and ApplyQueryAttributes to pass an IDictionary<string, object> query.
(The Xamarin example shows IDictionary<string, string>, but its , object in Maui, so you can pass any object values.)
Thus the string parameters you pass can be used to look up corresponding objects.
From that (Xamarin) doc (modified to show looking up an object):
public class MonkeyDetailViewModel : IQueryAttributable, ...
{
public MyData Data { get; private set; }
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
Data = (MyData)query["data"];
}
...
}
For Xamarin Forms, the limitation to string values makes this a bit ugly. One approach is to have a static that holds possible objects, which you look up using a string. This is tolerable when the objects are all pre-defined, but is a bit clumsy if you are manually altering those objects.
public class MonkeyDetailViewModel : IQueryAttributable, ...
{
public static Dictionary<string, MyData> KeyedData;
// "static": One-time class constructor.
public static MonkeyDetailViewModel()
{
KeyedData = new Dictionary<string, MyData>();
KeyedData["data1"] = new MyData(...);
// ... other versions of the data ...
}
public MyData Data { get; private set; }
public void ApplyQueryAttributes(IDictionary<string, string> query)
{
string whichData = query["data"]; // In example, gets "data1".
Data = KeyedData[whichData];
}
...
}
Usage:
await Shell.Current.GoToAsync("//myAwesomeUri",
new Dictionary { {"data", "data1"} });
Xamarin NOTE: The static dictionary makes it possible to maintain multiple instances of MyData. The "hack" alternative is to have MyData Data be static, and explicitly set it before GoToAsync - but this is risky if you ever might have a MonkeyDetailView on nav stack, go to a second one, then go back to first one - you'll have overwritten the Data seen by the first view.

Finding all Classes beloning to a superclass using Java 7

I'm looking for a way in java to find all classes that belongs to a certain superclass, and within that class refer to a static string with a known name (using reflection?);
public class Bar
extends ObjectInstance
{
public final static String Name = "Foo";
// more
}
From the example; there are n-occurences of classes that extend from ObjectInstance, and from all, i need the value of Name. The classes i am refering to are generated so i know for sure that there is a Name element that i can refer to, but i have no access to the generation sourcedata.
Perhaps the same question as How do you find all subclasses of a given class in Java?
This backs up my initial feeling that this can only be done like IDEs do it: by scanning everything down the tree, building your relationships as you go.
No Way.
One failing solution:
publc abstract class ObjectInstance {
public abstring String name();
private static Map<String, Class<? extends ObjectInstance> klasses =
new HashMap<>();
protected ObjectInstance() {
classes.put(name(), getClass());
}
Only collects instantiated classes! So fails.
With the idea to have the name provided by a function with return "foo";.
Collecting the class.
There are two unsatisfactory solutions:
The other way around: use the name as a factory pattern:
enum Name {
FOO(Bar.class),
BAZ(Baz.class),
QUX(Qux.class),
BAR(Foo.class);
public final Class<ObjectInstance> klass;
private Name(Class<ObjectInstance> klass) {
this.klass = klass;
}
}
Maybe as factory to create instances too.
Using a class annotation, and have a compile time scanning:
#ObjectInstanceName("foo")
public class Bar extends ObjectInstance {
}
How to apply this to your case: experiment.
There would be a more fitting solution of using your own ClassLoader, but that is far too over-engineered.

Data Transfer Object, Business Object, Domain Object or something else?

In database I have table: Notes and table Comments. In my solution I have 3 projects: DAL, BLL and Web.
I need to show a user notes with comments which aren't set as spam so I have created in DAL project that class:
public class NotesWithComments
{
public Notes Note { get; set; }
public IEnumerable<Comments> Comments { get; set; }
}
I use above class in each project: DAL, BLL and Web. Is this class Data Transfer Object, Business Object, Domain Object or what?
In a repository class I have that query:
public class NotesRepository
{
DatabaseContext context;
public NotesRepository(DatabaseContext context)
{
this.context = context;
}
public IQueryable<NotesWithComments> GetNotesWithNoSpamComments()
{
IQueryable<NotesWithComments> notesWithNoSpamComments = context.Notes.Include(x => x.Comments).OrderByDescending(x => x.CreateDate)
.Select(x => new NotesWithComments
{
Note = x,
Comments = x.Comments.Where(y => y.IsSpam == false).OrderBy(y => y.CreateDate)
});
return notesWithNoSpamComments;
}
}
In BLL project I use the method from the repository class:
public class NotesService
{
private readonly IUnitOfWork _unitOfWork;
public NotesService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public IEnumerable<NotesWithComments> GetNotesWithComments()
{
IQueryable<NotesWithComments> result = _unitOfWork.NotesRepository.GetNotesWithNoSpamComments();
return result;
}
}
And in Web project I use the method form the service class:
public ActionResult Index()
{
List<NotesWithComments> result = _notesService.GetNotesWithComments();
return View(result);
}
Since it neither exposes any behavior (properties or getters/setters don't qualify) nor encapsulates its structure (again, properties or getters/setters that do nothing but expose the underlying data don't qualify) it is no object at all.
No matter if the language you use calls it an object or not. It is just a data structure (which is perfectly fine if you only want to move data from one place, like a database, to another, like a UI.)
Or, to quote Dan North:
Data Transfer Object is an oxymoron
Is this class Data Transfer Object, Business Object, Domain Object or
what?
A DTO is typically a class that is mainly used for transferring data between layers or some type of boundaries..typically just an object with no behavior.
I have always referred to Domain Objects as something that maps directly to a database table. So In your example, your domain models would be Notes, and Comments.
I would consider your NotesWithComments object a dto, or possibly a view model (as you're using it as your asp.net mvc model for the view).
The practice I would normally use here is use your NotesWithComments as a dto (transfer data, no behavior, easily serializable, very clean ect), and create another class to act as your view model.
In the beginning these classes would probably be very similar, possibly the same..but if you make changes over time, or your view needs to display different things, you would just change your view model, and populate it from other dtos, or tranform your data however you need to. You could also then get rid of the properties on your view model that your view doesn't need.. (unless your view magically maps directly to every property on your current dto). It's a bit more work up front but if you're working on a big long living project I think you'd be happy you did it later on.
So you would populate your domain models using EF in your data layer, you would then use your dto and transfer that data to the Biz layer, do w/e you need there, then use your dto (could be the same one) to transfer your data to your presentation layer (mvc), and populate your view model from the dtos you receive.
Anyway that's my take on it.

ASP.NET MVC to Existing ASP.NET App with BusinessLayer.Better way to load ViewModel objects from Existing BusinessLayer?

I have a legacy asp.net web application which has 2 layers , UI and BusinessLayer. The UI project is of type ASP.NET website and BL is of type class library. The BL project has classes for entities of my app like Customer,User,Empoloyee etc.. Each class has methods for Reading from Database and Populate the object properties from the DataReader.that means the Customer Class contains my Customer object and Data Access Methods together.
Now I changed the web app to support MVC too. The old site (webforms) works as it used to be and the new upgrade to the site i am making (adding admin features to manage the site) is in ASP.NET MVC3. The routing and everything works fine. But i am worried about the structure /maintainability of the project.
For the new MVC part, I had to create ViewModels for few of the Entities like CustomerViewModel,EmployeeViewModel. I created another class called "CustomerService" With methods like GetCustomerViewModel and inside that method i call the GetCustomerMethod from the Existing BusinessLayer and read property values from the object ( of entity type mentioned in the existing BL project) and assign that to the CustomerViewModel (I will look into some AutoMapper samples for this later)object and return that from this method. My View will use this object to show data in the UI. The reason i created the "CustomerService" class is i may need to do some if condition checking or some business validations before setting the values to CustomerViewModel object. I consider that as a "Middle Layer / Service layer" so that my Controllers will be thin.
From my Customer Controller
public ActionResult Details(int id)
{
MyProject.MVCViewModel.CustomerViewModel objCustomerVM;
objCustomerVM=MyProject.MVCMiddleLayer.CustomerService.GetCustomerViewModel(id);
return View(objCustomerVM);
}
In my CustomerViewModel
public static CustomerViewModel GetCustomerViewModel(int customerId)
{
//Create an object of new ViewModel
CustomerViewModel objCustomerViewModel = new CustomerViewModel ();
//Get an object from Existing BL of Customer of type ExistingBL.Customer
ExistingBL.Customer objCustOld=new Customer(customerId);
//Check some properties of the customer object and set values to the new ViewModel object
if(objCustOld.Type=="normal")
{
objCustomerViewModel.Priority=2;
}
else if(objCustOld.Type=="abnormal")
{
objCustomerViewModel.Priority=1;
objCustomerViewModel.Message ="We love you";
}
//Some other checking like this....
return objCustomerViewModel;
}
Is this a wrong approach ? Is my code going to be messy ? I am not happy about the ViewModel since it is (almost) the duplicate code from my Existing BL entities. What is the best way to address this scenario. I am not sure about using Repository Pattern (which i saw in most of the examples) in this case ? Should i do that ?How is it going to improve my code ?
The approach that I would take would be similar to repository pattern. I would outline few key points
Since the only thing that you would be rewriting would be UI logic (View Model Object), and its fine as your UI technologies are different(asp.net vs MVC)
I would suggest you start working on interfaces so that later on you could do a dependency injection. The biggest benefit I generally with dependecy injection in mvc is while writing NUnit test cases.
public static ICustomerViewModel GetCustomerViewModel(int customerId)
{
//use DI, rather than concerete implementation
ICustomerViewModel objCustomerViewModel = new CustomerViewModel ();
//use DI, rather than concerete implementation
ExistingBL.ICustomer objCustOld=new Customer(customerId);
.
.
.
return objCustomerViewModel;
}
You could now very easily create mock objects with the help of any mocking frame work.
More or less my ViewModel classes are a redefinition of properties with only attributes, someone may argue that this is just another overhead layer, but I do this for a simple reason: I can add proper Web Validation's attributes without breaking anything (The DataLayer shoudl be shareable with other apps).
In shorts given a DataLayer class exposing a User object:
public class DalUser {
public int Id { get; set;}
public int Age { get; set;}
public string Name { get; set;}
public string Surname { get; set;}
// Business method for reading/writing/deleting
}
My viewmodel is something like:
public class VmUser : DalUser
{
[Display(Name="ID Code")]
public override int Id { get; set; }
[Display(Name="Age")]
[Required]
public override int Age { get; set; }
}
This leads me to two goals: the former is I can use Attributes without worrying about breaking something else, the latter is I can hide from user some field, prevent field injection (e.g. from FireBug - but that's includes defining an Interface and using that, not plain subclassing).
That's proves pretty usefull within my corporate (we're doomed to use EntitySpaces) and it's one of the less ugly way I've found in order to partially reuse ES generated classes.

Is it possible to remove properties from a dynamic class?

I have a dynamic ActionScript Class that is used to send parameters to a WebService. Some of these parameters are always present, so they are public properties of the Class:
package
{
[Bindable]
public dynamic class WebServiceCriteria
{
public var property1:int;
public var property2:String;
public var property3:String;
public var property4:String;
}
}
But, I am also adding properties at runtime that can change over time:
criteria.runTimeProperty = "1";
I'm not very familiar with using dynamic classes, so I was wondering if it is possible to "remove" the new property. Let's say the next time I call the WebService I don't want that property sent - not even as a null. How can I remove it from the Class instance without creating a new instance each time?
I believe all you'd need to do is this:
delete criteria.runTimeProperty;
or
delete criteria["runTimeProperty"];
Either should do the same thing.
See the delete documentation for specifics.

Resources