Load objects which have been initialized before attaching - java-bytecode-asm

I am trying to load objects through bytecode instrumentation , using asm framework.
Now , when I am using premain , all the objects I can track accurately. But, with attach , is there any way out to do so ?
Let's take an example :
private ArrayList<Integer> list = new ArrayList<Integer>();
public void insertValues(int limit){
if(list!=null){
for(int i=0;i<limit;i++){
list.add(i);
}
}
}
Now , if this list is not called again ( which I can track from visitFieldInsn : GETFIELD opcode ) , I can not load this object , right ?
Is there any workaround from this problem ?
Any help in this regard is much appreciated .

Related

Filtering out soft deletes with AutoQuery

I'm using ServiceStack with OrmLite, and having great success with it so far. I'm looking for a way to filter out 'soft deleted' records when using AutoQuery. I've seen this suggestion to use a SqlExpression, but I'm not sure where you would place that. In the AppHost when the application starts? I did that, but the deleted records still return. My QueryDb request object in this case is as follows:
public class QueryableStore : QueryDb<StoreDto>
{
}
Other SqlExpressions I've used are in the repository class itself, but being that I'm using QueryDb and only the message itself (not leveraging my repository class) I don't have any other code in place to handle these messages and filter out the 'deleted' ones.
I've also tried using a custom service base as suggested by this approach as well, using the following:
public abstract class MyCustomServiceBase : AutoQueryServiceBase
{
private const string IsDeleted = "F_isdeleted";
public override object Exec<From>(IQueryDb<From> dto)
{
var q = AutoQuery.CreateQuery(dto, Request);
q.And("{0} = {1}", IsDeleted, 0);
return AutoQuery.Execute(dto, q);
}
public override object Exec<From, Into>(IQueryDb<From, Into> dto)
{
var q = AutoQuery.CreateQuery(dto, Request);
q.And("{0} = {1}", IsDeleted, 0);
return AutoQuery.Execute(dto, q);
}
}
This code gets called, but when the Execute call happens I get an error:
System.ArgumentException: 'Conversion failed when converting the varchar value 'F_isdeleted' to data type int.'
The F_isdeleted column is a 'bit' in SQL Server, and represented as a bool in my POCO.
Any ideas on what would work here? I'm kind of at a loss that this seems this difficult to do, yet the docs make it look pretty simple.
The {0} are placeholders for db parameters, so your SQL should only be using placeholders for DB parameters, e.g:
var q = AutoQuery.CreateQuery(dto, Request);
q.And(IsDeleted + " = {0}", false);
Otherwise if you want to use SQL Server-specific syntax you can use:
q.And(IsDeleted + " = 0");

How to use ObjectContext.LoadProperty with EnablePlanCaching disabled?

On an ObjectContext object, I'm using code like this to load navigation properties.
context.LoadProperty(entity, navigationProperty,
System.Data.Objects.MergeOption.AppendOnly);
I would like to disable plan caching on queries that will be generated with this kind of call ?
Is it possible ?
Is there an alternative by wrapping the context with a DBContext ?
Thanks in advance.
I solved the problem by using a DBContext.
DbContext dbc = new DbContext(context, false);
dbc.Entry<T>(object).Reference<TReference>(#"ReferenceName").Query().DisablePlanCaching().Load();
dbc.Entry<T>(object).Collection<TCollection>(#"CollectionName").Query().DisablePlanCaching().Load();
with DisablePlanCaching extension method (inspired from the one found here) as :
public static IQueryable<T> DisablePlanCaching<T>(this IQueryable<T> query)
{
ObjectQuery<T> q = query as ObjectQuery<T>;
if ( q == null )
throw new InvalidOperationException(#"IQueryable<T> is not of type ObjectQuery<T>");
q.EnablePlanCaching = false;
return query;
}

Customs binding cross views in mvvmcross

I need a custom binding and I know when and where but I don't know how I can do it. This is the relation of the view in my custom binding. Think about the *Views like controls.
I have the connections from ViewModel->ContainerView->FirstView but I can't connect it with the TableView. To connect the ContainerView to FirstView I did a custom binding (in one direction for now). And in the setvalue method I call the firstview's method SetBinding (where I want to do the binding)
I tried a few option but nothing happens, the last one looks like this:
public GolferList CurrentGolferList { get; set; }
public void SetBinding(GolferList golferList){
this.CurrentGolferList = golferList;
TableSource = new TableSourcePlayers(TableViewPlayers);
var bindingDescription = new[]{
new MvxBindingDescription {TargetName = "ItemsSource",SourcePropertyPath = "CurrentGolferList"} ,
};
Binder.Bind(this,TableSource, bindingDescription);
TableViewPlayers.Source = TableSource;
TableViewPlayers.ReloadData();
}
I would be grateful if you could tell me another way to handle it.
Update:
I followed Stuart's link and now it works fine, thanks a lot Stuart!
Actually, in my scheme the TableView is a MvxSimpleBindableTableViewSource and I want to bind the data there. So in order to make it work, I used the code below (SetBinding needs some external refactor):
private List<IMvxUpdateableBinding> bindings;
private string BindingText = "{'ItemsSource':{'Path':'CurrentGolfers'}}";
public object DataContext {
get { return dataContext; }
set { dataContext = value;
if (bindings == null)
bindings = this.GetService<IMvxBinder>().Bind(dataContext, TableSource, BindingText).ToList();
else
bindings.ForEach(b => b.DataContext = dataContext);
}
}
public void SetBinding(GolferList golferList){
this.DataContext = PlayViewModel;
tableView.Source = TableSource;
tableView.ReloadData();
}
Note that BindingText points to the table, not to the view itself.
Update 2
Now in V3 it's a bit different. First, the view must implement IMvxBindable and this members:
public object DataContext
{
get { return BindingContext.DataContext; }
set { BindingContext.DataContext = value; }
}
public IMvxBindingContext BindingContext { get; set; }
(Don't forget dispose calling BindingContext.ClearAllBindings() and also call to CreateBindingContext() in the viewload )
And then you'll be able to bind in your class. In my case:
var set = this.CreateBindingSet<FirstPlayViewController, PlayViewModel>();
set.Bind(source).To(vm => vm.CurrentGolfers).Apply(); //I love the new fluent api :)
I think what you want to do is actual a data-bound View, rather than a custom binding.
This is covered in this question - Custom bindable control in a MvvmCross Touch project
Basically what you need to do is to add a collection of 'Bindings' and the 'DataContext' property to your FirstView.
If you do that then you should be able to databind (to DataContext) within FirstView just like you do within any normal MvvmCross view.
Note - this will be much easier to do in v3 as we've added a 'BindingContext' object to assist with exactly this type of operation

Reusable generic LightSwitch screen with WCF RIA Services

I'm new to WCF RIA Services, and have been working with LightSwitch for 4 or so months now.
I created a generic screen to be used for editing lookup tables all over my LightSwitch application, mostly to learn how to create a generic screen that can be used with different entity sets on a dynamic basis.
The screen is pretty simple:
Opened with arguments similar to this:
Application.ShowLookupTypesList("StatusTypes", "StatusTypeId"); which correspond to the entity set for the lookup table in the database.
Here's my WCF RIA service code:
using System.Data.Objects.DataClasses;
using System.Diagnostics;
using System.Reflection;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Server;
namespace WCF_RIA_Project
{
public class LookupType
{
[Key]
public int TypeId { get; set; }
public string Name { get; set; }
}
public static class EntityInfo
{
public static Type Type;
public static PropertyInfo Key;
public static PropertyInfo Set;
}
public class WCF_RIA_Service : LinqToEntitiesDomainService<WCSEntities>
{
public IQueryable<LookupType> GetLookupTypesByEntitySet(string EntitySetName, string KeyName)
{
EntityInfo.Set = ObjectContext.GetType().GetProperty(EntitySetName);
EntityInfo.Type = EntityInfo.Set.PropertyType.GetGenericArguments().First();
EntityInfo.Key = EntityInfo.Type.GetProperty(KeyName);
return GetTypes();
}
[Query(IsDefault = true)]
public IQueryable<LookupType> GetTypes()
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
var types = from e in set
select new LookupType
{
TypeId = (int)EntityInfo.Key.GetValue(e, null),
Name = (string)EntityInfo.Type.GetProperty("Name").GetValue(e, null)
};
return types.AsQueryable();
}
public void InsertLookupType(LookupType lookupType)
{
dynamic e = Activator.CreateInstance(EntityInfo.Type);
EntityInfo.Key.SetValue(e, lookupType.TypeId, null);
e.Name = lookupType.Name;
dynamic set = EntityInfo.Set.GetValue(ObjectContext, null);
set.AddObject(e);
}
public void UpdateLookupType(LookupType currentLookupType)
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
dynamic modified = set.FirstOrDefault(t => (int)EntityInfo.Key.GetValue(t, null) == currentLookupType.TypeId);
modified.Name = currentLookupType.Name;
}
public void DeleteLookupType(LookupType lookupType)
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
var e = set.FirstOrDefault(t => (int)EntityInfo.Key.GetValue(t, null) == lookupType.TypeId);
Debug.Assert(e.EntityState != EntityState.Detached, "Entity was in a detached state.");
ObjectContext.ObjectStateManager.ChangeObjectState(e, EntityState.Deleted);
}
}
}
When I add an item to the list from the running screen, save it, then edit it and resave, I receive data conflict "Another user has deleted this record."
I can workaround this by reloading the query after save, but it's awkward.
If I remove, save, then readd and save an item with the same name I get unable to save data, "The context is already tracking a different entity with the same resource Uri."
Both of these problems only affect my generic screen using WCF RIA Services. When I build a ListDetail screen for a specific database entity there are no problems. It seems I'm missing some logic, any ideas?
I've learned that this the wrong approach to using LightSwitch.
There are several behind-the-scenes things this generic screen won't fully emulate and may not be do-able without quite a bit of work. The errors I've received are just one example. LightSwitch's built-in conflict resolution will also fail.
LS's RAD design means just creating a bunch of similar screens is the way to go, with some shared methods. If the actual layout needs changed across many identical screens at once, you can always find & replace the .lsml files if you're careful and make backups first. Note that modifying these files directly isn't supported.
I got that error recently. In my case I create a unique ID in my WCF RIA service, but in my screen behind code I must explicitly set a unique ID when I create the object that will later be passed to the WCF RIA Service insert method (this value will then be overwritten with the unique counter ID in the table of the underlying database).
See the sample code for this project:
http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/157/A-Visual-Studio-LightSwitch-Picture-File-Manager.aspx

SubSonic SimpleRepository Updates Cause Null Reference Exceptions

In researching the SubSonic's new SimpleRepository, I've found that calling the Update() method always throws a NullReferenceException. This is even true in the sample MVC download that's included with the 3.0.0.3 release.
Does anyone know if there's a way to get updates to succeed?
Here's an example. The if statement works; it adds the table and creates the record. Running this code a second time flow to the else block, and the update throws the exception.
var repo = new SimpleRepository("c", SimpleRepositoryOptions.RunMigrations);
var user = repo.Single<User>(u => u.Email == "a#b.com");
if (user == null)
{
repo.Add(new User { Email = "a#b.com", Name = "Test" });
}
else
{
user.Name = DateTime.Now.ToString();
repo.Update(user);
}
public class User
{
public int Key { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
I think I found the problem. In the SubSonic source there's a minor flaw in the Update routine where it queries the list of tables in the update query object for a column name. The Linq query needed to use the column's QualifiedName property, not the Name property. The query settings (which is the right hand side of the query) uses the fully qualified name.
I took the liberty of submitting an issue on SubSonic's GitHub site as well :)
For those interested, the issue is in Update.cs (in the Query folder), Line 229.
Change this...
var col= table.Columns.SingleOrDefault(
x => x.Name.Equals(s.ColumnName, StringComparison.InvariantCultureIgnoreCase)
);
to this...
var col = table.Columns.SingleOrDefault(
x => x.QualifiedName.Equals(
s.ColumnName, StringComparison.InvariantCultureIgnoreCase
)
);
Rebuild and you're good to go.
I ran into this problem as well and I was able to download the latest SubSonic source and the issue was already fixed. Just open the SubSonic.Core project and do a build and replace your project's reference to SubSonic.Core.
Download Latest Source
http://github.com/subsonic/SubSonic-3.0
Boom - Repository Update works again!

Resources