Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

2008-06-09 Thread Gilles Bayon
I haven't had time yesterday...I will do that today


-- 
Cheers,
Gilles


Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

2008-06-09 Thread Ron Grabowski
There's still some other interfaces that need changed over? 
IResultMapEventListener and IResultPropertyEventListener?


- Original Message 
From: Gilles Bayon <[EMAIL PROTECTED]>
To: dev@ibatis.apache.org
Sent: Monday, June 9, 2008 12:57:19 PM
Subject: Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

I liked it too, will changed to


-- 
Cheers,
Gilles


Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

2008-06-09 Thread Gilles Bayon
I liked it too, will changed to


-- 
Cheers,
Gilles


Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

2008-06-09 Thread Ron Grabowski
I don't think you need to actually call GetInvocationList since the delegates 
are all combined to appear as a single item:

// TODO: change this over to use generics
protected virtual object RaisePreInsert(object parameterObject, object 
resultObject)
{
EventHandler handlers = 
(EventHandler)events[PreInsertEvent];

StatementEventArgs eventArgs = new StatementEventArgs();
eventArgs.MappedStatement = this;
eventArgs.ResultObject = resultObject;
eventArgs.ParameterObject = parameterObject;

// should process _all_ the listeners
handlers(this, eventArgs);

return eventArgs.ResultObject;
}


- Original Message 
From: Ron Grabowski <[EMAIL PROTECTED]>
To: dev@ibatis.apache.org
Sent: Monday, June 9, 2008 12:40:50 PM
Subject: Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?


Delegates are only fire and forget if you BeginInvoke them...this is a 
sequential implementation:

// TODO: change this over to use generics
protected virtual object RaisePreInsert(object parameterObject, object 
resultObject)
{
EventHandler handlers = 
(EventHandler)events[PreInsertEvent];

StatementEventArgs eventArgs = new StatementEventArgs();
eventArgs.MappedStatement = this;
eventArgs.ResultObject = resultObject;
eventArgs.ParameterObject = parameterObject;

foreach (EventHandler handler in handlers.GetInvocationList())
{
handler.Invoke(this, eventArgs);
}

return eventArgs.ResultObject;
}

Each subscriber should be able to update/change/proxy ResultObject before its 
returned:

 mappedStatement.PreInsert += (s, e) => { ((User)e.ResultObject).CreatedDate = 
DateTime.Now ; }
 mappedStatement.PreInsert += (s, e) => { e.ResultObject = 
createProxy((User)e.ResultObject); }


- Original Message 
From: Gilles Bayon <[EMAIL PROTECTED]>
To: dev@ibatis.apache.org
Sent: Monday, June 9, 2008 2:20:20 AM
Subject: Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

The .NET event pattern cannot be used here, it follows the pattern fire and 
forget, and it's not what I'm searching as I want to be able to interact with 
the DataMapper workflow engine, you must see them as extension point where you 
can change the items that the engine is working on.
It can be used for all sorts of cross-cutting concerns

Example, replace the resultMap object instance by a proxy one, add/change 
arguments used by the constructor in the resultMap...

private class MyPreCreateEventListener : PreCreateEventListener
{
/// 
/// Calls before creating an instance of the  
object.
/// 
/// The event.
/// 
/// Returns is used as constructor arguments for the instance being created
/// 
public override object OnEvent(PreCreateEvent evnt)
{
evnt.Parameters[evnt.Parameters.Length-1] = "new lastName";

return evnt.Parameters;
}
}

Example

private class MyPreInsertEventListener :PreInsertEventListener
{

/// 
/// Calls on the specified event.
/// 
/// The event.
/// Returns is used as the parameter object
public override object OnEvent(PreInsertEvent evnt)
{
IDomain domain = evnt.ParameterObject as IDomain;
if (domain != null)
{
ProcessBeforeInsert(domain);
}

return account;
}

private void ProcessBeforeInsert(IDomain domain)
{
User user = (User) Thread.CurrentPrincipal;
domain.CreatedBy = user.UserName;
domain.ModifiedBy = user.UserName;
domain.CreatedDate = DateTime.Now;
domain.ModifiedDate = DateTime.Now;
}
 }

-- 
Cheers,
Gilles


Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

2008-06-09 Thread Ron Grabowski
Delegates are only fire and forget if you BeginInvoke them...this is a 
sequential implementation:

// TODO: change this over to use generics
protected virtual object RaisePreInsert(object parameterObject, object 
resultObject)
{
EventHandler handlers = 
(EventHandler)events[PreInsertEvent];

StatementEventArgs eventArgs = new StatementEventArgs();
eventArgs.MappedStatement = this;
eventArgs.ResultObject = resultObject;
eventArgs.ParameterObject = parameterObject;

foreach (EventHandler handler in handlers.GetInvocationList())
{
handler.Invoke(this, eventArgs);
}

return eventArgs.ResultObject;
}

Each subscriber should be able to update/change/proxy ResultObject before its 
returned:

 mappedStatement.PreInsert += (s, e) => { ((User)e.ResultObject).CreatedDate = 
DateTime.Now ; }
 mappedStatement.PreInsert += (s, e) => { e.ResultObject = 
createProxy((User)e.ResultObject); }


- Original Message 
From: Gilles Bayon <[EMAIL PROTECTED]>
To: dev@ibatis.apache.org
Sent: Monday, June 9, 2008 2:20:20 AM
Subject: Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

The .NET event pattern cannot be used here, it follows the pattern fire and 
forget, and it's not what I'm searching as I want to be able to interact with 
the DataMapper workflow engine, you must see them as extension point where you 
can change the items that the engine is working on.
It can be used for all sorts of cross-cutting concerns

Example, replace the resultMap object instance by a proxy one, add/change 
arguments used by the constructor in the resultMap...

private class MyPreCreateEventListener : PreCreateEventListener
{
/// 
/// Calls before creating an instance of the  
object.
/// 
/// The event.
/// 
/// Returns is used as constructor arguments for the instance being created
/// 
public override object OnEvent(PreCreateEvent evnt)
{
evnt.Parameters[evnt.Parameters.Length-1] = "new lastName";

return evnt.Parameters;
}
}

Example

private class MyPreInsertEventListener :PreInsertEventListener
{

/// 
/// Calls on the specified event.
/// 
/// The event.
/// Returns is used as the parameter object
public override object OnEvent(PreInsertEvent evnt)
{
IDomain domain = evnt.ParameterObject as IDomain;
if (domain != null)
{
ProcessBeforeInsert(domain);
}

return account;
}

private void ProcessBeforeInsert(IDomain domain)
{
User user = (User) Thread.CurrentPrincipal;
domain.CreatedBy = user.UserName;
domain.ModifiedBy = user.UserName;
domain.CreatedDate = DateTime.Now;
domain.ModifiedDate = DateTime.Now;
}
 }

-- 
Cheers,
Gilles


Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

2008-06-08 Thread Gilles Bayon
The .NET event pattern cannot be used here, it follows the pattern fire and
forget, and it's not what I'm searching as I want to be able to interact
with the DataMapper workflow engine, you must see them as extension point
where you can change the items that the engine is working on.
It can be used for all sorts of cross-cutting concerns

Example, replace the resultMap object instance by a proxy one, add/change
arguments used by the constructor in the resultMap...

private class MyPreCreateEventListener : PreCreateEventListener
{
/// 
/// Calls before creating an instance of the 
object.
/// 
/// The event.
/// 
/// Returns is used as constructor arguments for the instance being
created
/// 
public override object OnEvent(PreCreateEvent evnt)
{
evnt.Parameters[evnt.Parameters.Length-1] = "new lastName";

return evnt.Parameters;
}
}

Example

private class MyPreInsertEventListener :PreInsertEventListener
{

/// 
/// Calls on the specified event.
/// 
/// The event.
/// Returns is used as the parameter object
public override object OnEvent(PreInsertEvent evnt)
{
IDomain domain = evnt.ParameterObject as IDomain;
if (domain != null)
{
ProcessBeforeInsert(domain);
}

return account;
}

private void ProcessBeforeInsert(IDomain domain)
{
User user = (User) Thread.CurrentPrincipal;
domain.CreatedBy = user.UserName;
domain.ModifiedBy = user.UserName;
domain.CreatedDate = DateTime.Now;
domain.ModifiedDate = DateTime.Now;
}
 }

-- 
Cheers,
Gilles


Re: svn commit: r664536 [1/4]...EventHandler/EventArgs?

2008-06-08 Thread Ron Grabowski
Don't most (all?) events in .NET follow the EventHandler/EventArgs pattern:

 public class StatementEventArgs : EventArgs
 {
  public IMappedStatement MappedStatement;
  public StatementEventType Type;
  public object ParameterObject;
  public object Result;
 }

 public interface IMappedStatementEvents
 {
  event EventHandler PreInsert;
  event EventHandler PreSelect;
  event EventHandler PreUpdateOrDelete;
  event EventHandler PostInsert;
  event EventHandler PostSelect;
  event EventHandler PostUpdateOrDelete;  
 }

 // Castle.MicroKernel.KernelEventSupport
 public class MappedStatementEventSupport : IMappedStatementEvents
 {
  private static readonly object PreInsertEvent = new object();
  // snip

  private EventHandlerList events = new EventHandlerList();

  public event EventHandler PreInsert
  {
  add { events.AddHandler(PreInsertEvent, value); }
  remove { events.RemoveHandler(PreInsertEvent, value); }
  }

  protected virtual object RaisePreInsert(IMappedStatement mappedStatement, 
object parameterObject)
  {
   EventHandler handler = 
(EventHandler) events[PreInsertEvent];
   // TODO: create StatementEventArgs and Invoke each item in 
handler.GetInvocationList()
  }

  // snip
 }

 public class MappedStatement : MappedStatementEventSupport, IMappedStatement
 {
  // add calls to raise events: RaisePreInsert(mappedStatement, 
parameterObject);
 }

Is there a reason why we rolled our own? 

I like this:

 mappedStatement.PreInsert += (s, e) => { 
Console.WriteLine(e.MappedStatement.Id); }

This seems like a lot of code just to register MyConsoleWriter:

 // ???
 PreInsetEventListener[] preInsertEvents = 
  new PreInsetEventListener[mappedStatement.PreInsertListeners.Length + 1];
 mappedStatement.PreInsetEventListener.CopyTo(preInsertEvents, 0);
 preInsertEvents.SetValue(
  new MyConsoleWriter(), 
  mappedStatement.PreInsetEventListener.Length);
 mappedStatement.PreInsetEventListener = preInsertEvents;

Maybe the listeners should be exposed as 
System.Collection.Generic.ICollection:

 mappedStatement.PreInsetEventListener.Add(new MyConsoleWriter());

Also note that I had to write my own class, MyConsoleWriter, instead of just 
the short lambda expression. The standard EventHandler/EventArgs model makes 
the most sense to me.

- Original Message 
From: "[EMAIL PROTECTED]" <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED]
Sent: Sunday, June 8, 2008 2:20:46 PM
Subject: svn commit: r664536 [1/4] - in /ibatis/trunk/cs/V3/src: 
Apache.Ibatis.DataMapper.SqlClient.Test.2005/ 
Apache.Ibatis.DataMapper.SqlClient.Test.2005/Fixtures/ 
Apache.Ibatis.DataMapper.SqlClient.Test.2005/Fixtures/Mapping/ 
Apache.Ibatis.DataMapper.SqlClie...

Author: gbayon
Date: Sun Jun  8 11:20:44 2008
New Revision: 664536

URL: http://svn.apache.org/viewvc?rev=664536&view=rev
Log:
IBATISNET-271 add event support

Added:

ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test.2005/Fixtures/Mapping/EventTest.cs
   (with props)

ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test.2005/Fixtures/Modules/EventModule.cs
   (with props)

ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test.2005/Fixtures/ScriptBase.cs
   (with props)

ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test.2005/Maps/Event.xml

ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper.SqlClient.Test.2005/bin/Debug/SqlMap.event.config

ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/DataMapperLocalSessionScope.cs  
 (with props)
ibatis/trunk/cs/V3/src/Apache.Ibatis.DataMapper/Model/Events/

[snip]