[ComponentBehavior] register viewmodel with interface problem.

8 views
Skip to first unread message

ktu...@gmail.com

unread,
Oct 17, 2010, 8:12:47 PM10/17/10
to uNhAddIns
Hello everyone,

Currently i used ComponentBehavior for a ViewModel to add
INotifyPropertyChanged and IErrorDataInfo:

public class MyViewModel : IMyViewModel
{
}

it will fail when register using:
container.Register(Component.For<IMyViewModel>().ImplementedBy<MyViewModel>().LifeStyle.Transient);

but when i register:
container.Register(Component.For<MyViewModel>().LifeStyle.Transient);
it work perfectly

is it possible to do that? or am i miss something?


Regards
ktutnik


Note: here is my configuration:

===== Facilities:

container.AddFacility<FactorySupportFacility>();
container.AddFacility<ComponentBehaviorsFacility>();
container.AddFacility<PersistenceConversationFacility>();

container.Register(Component.For<IBehaviorStore>().ImplementedBy<BehaviorDictionary>());

===== ViewModel Registration:

var behaviorStore =
(BehaviorDictionary)container.Resolve<IBehaviorStore>();
behaviorStore.For<MyViewModel >()
.Add<NotifyPropertyChangedBehavior>()
.Add<DataErrorInfoBehavior>();

===== Validation Configuration:

var validatorsDev = Factory.GetExtension<IValidationMarker>();
var configuration = new FluentConfiguration();
configuration.Register(validatorsDev)
.SetDefaultValidatorMode(ValidatorMode.UseExternal)
.AddEntityTypeInspector<NHVTypeInspector>();

var engine = new ValidatorEngine();
engine.Configure(configuration);
var entityValidator = new EntityValidator(engine);

container.Register(Component.For<IEntityValidator>().Instance(entityValidator));



José F. Romaniello

unread,
Oct 17, 2010, 9:32:41 PM10/17/10
to unha...@googlegroups.com
and the exception/stacktrace is ....?

ktu...@gmail.com

unread,
Oct 17, 2010, 10:53:53 PM10/17/10
to uNhAddIns
Sorry,, it was not failed (error) but not working expectedly.

when i do:

((IDataErrorIndo)mymodelInstance).Errors --> empty (but actually it
should be not empty)

I found something strange (i don't know it is mean something or not):

((IWellKonwnProxy)mymodelInstance).EntityType --> System.Object



On Oct 18, 9:32 am, José F. Romaniello <jfromanie...@gmail.com> wrote:
> and the exception/stacktrace is ....?
>
> 2010/10/17 ktut...@gmail.com <ktut...@gmail.com>
>
>
>
> > Hello everyone,
>
> > Currently i used ComponentBehavior for a ViewModel to add
> > INotifyPropertyChanged and IErrorDataInfo:
>
> > public class MyViewModel : IMyViewModel
> > {
> > }
>
> > it will fail when register using:
>
> > container.Register(Component.For<IMyViewModel>().ImplementedBy<MyViewModel> ().LifeStyle.Transient);
>
> > but when i register:
> > container.Register(Component.For<MyViewModel>().LifeStyle.Transient);
> > it work perfectly
>
> > is it possible to do that? or am i miss something?
>
> > Regards
> > ktutnik
>
> > Note: here is my configuration:
>
> > ===== Facilities:
>
> > container.AddFacility<FactorySupportFacility>();
> >            container.AddFacility<ComponentBehaviorsFacility>();
> >            container.AddFacility<PersistenceConversationFacility>();
>
> > container.Register(Component.For<IBehaviorStore>().ImplementedBy<BehaviorDi ctionary>());

José F. Romaniello

unread,
Oct 18, 2010, 12:30:16 AM10/18/10
to unha...@googlegroups.com
Try with behaviorStore.For<IMyViewModel>()...

2010/10/17, ktu...@gmail.com <ktu...@gmail.com>:

--
Enviado desde mi dispositivo móvil

ktu...@gmail.com

unread,
Oct 18, 2010, 12:52:48 AM10/18/10
to uNhAddIns
thanks for reply,

I have tried it to use behaviorStore.For<IMyViewModel>(), but didn't
work either. Previously i though that NHVTypeInspector failed to get
the actual (real) type. even i tried to create ValidationDef for
IMyModel, but still didn't help..

sorry currently now I'm at work, I can't give you an accurate
information for any clue. but i will ASAP.

On Oct 18, 12:30 pm, José F. Romaniello <jfromanie...@gmail.com>
wrote:
> Try with behaviorStore.For<IMyViewModel>()...
>
> 2010/10/17, ktut...@gmail.com <ktut...@gmail.com>:

ktu...@gmail.com

unread,
Oct 18, 2010, 12:59:37 AM10/18/10
to uNhAddIns
FYI, i used the branch for NH 2.1.2 (before the unhaddins migrated to
mercurial)

ktu...@gmail.com

unread,
Oct 18, 2010, 8:41:56 AM10/18/10
to uNhAddIns
More information:

when i use behaviorStore.For<IMyViewModel>() the
container.Resolve<IMyViewModel>() return MyModel instance (without
being proxied by castle)

when i use behaviorStore.For<MyViewModel>()the
container.Resolve<IMyViewModel>() return proxied of
IMyViewModelPoxyc2344xxxxxxx but the IWellKnownProxy.EntityName -->
System.Object and IDataErrorInfo.Error -> empty.

any idea?

José F. Romaniello

unread,
Oct 18, 2010, 10:49:18 PM10/18/10
to unha...@googlegroups.com
thanks KTutnik for reporting it.. I just fixed :)
This is the tests that i wrote to describe your problem:

would you mind to try trunk version and let me know if it is working now? or if you find another issue...
thank you

ktu...@gmail.com

unread,
Oct 18, 2010, 11:03:06 PM10/18/10
to uNhAddIns
thanks for the quick fix..

sure, i will try the trunk version.

On Oct 19, 10:49 am, José F. Romaniello <jfromanie...@gmail.com>
wrote:
> thanks KTutnik for reporting it.. I just fixed :)
> This is the tests that i wrote to describe your problem:http://code.google.com/p/unhaddins/source/browse/uNhAddIns/uNhAddIns....
>
> would you mind to try trunk version and let me know if it is working now? or
> if you find another issue...
> thank you
>
> 2010/10/18 ktut...@gmail.com <ktut...@gmail.com>

ktu...@gmail.com

unread,
Oct 19, 2010, 5:07:32 PM10/19/10
to uNhAddIns
Hello again,

i used the latest code from the trunk, the validation is work
perfectly. but now I faced another problem: Property of a class
registered with NotifyPropertyChangedBehavior when called from inside
of its class will never raise INotifyPropertyChanged.PropertyChanged
event.
to help quickly understand what i mean i wrote a unit testing below.
(sorry i wrote it using vs team system).
actually i though it was the behavior of CastleDynamicProxy, not a bug
in componentbehavior instead,, but i'm not really sure, let the
masters decide it.

regards
ktutnik.


================ Unit test

/*usings cutted*/
using SysCom = System.ComponentModel;

namespace ExperimentalTest.ComponentBehavior
{
public class CustomerWithNoInterface
{
public virtual string Email { get; set; }


public void ChangeEmail()
{
Email = "NEW_MAIL";
}
}

public class Customer : ICustomer
{
public virtual string Email { get; set; }


public void ChangeEmail()
{
Email = "NEW_MAIL";
}
}

public interface ICustomer
{
string Email { get; set; }
void ChangeEmail();
}

public class CustomerValidationDef : ValidationDef<ICustomer>
{
public CustomerValidationDef()
{
Define(x =>
x.Email).IsEmail().WithMessage("INCORRECT_EMAIL_MESSAGE");
}
}

public class CustomerNoInterfaceValidationDef :
ValidationDef<CustomerWithNoInterface>
{
public CustomerNoInterfaceValidationDef()
{
Define(x =>
x.Email).IsEmail().WithMessage("INCORRECT_EMAIL_MESSAGE");
}
}


[TestClass]
public class InheritanceTest
{
WindsorContainer container = null;

[TestInitialize]
public void Initialize()
{
container = new WindsorContainer();
container.AddFacility<FactorySupportFacility>();
container.AddFacility<ComponentBehaviorsFacility>();
container.AddFacility<PersistenceConversationFacility>();

var configuration = new FluentConfiguration();
configuration.Register(new Type[]
{ typeof(CustomerValidationDef),
typeof(CustomerNoInterfaceValidationDef) })
.SetDefaultValidatorMode(ValidatorMode.UseExternal)
.AddEntityTypeInspector<NHVTypeInspector>();
var engine = new ValidatorEngine();
engine.Configure(configuration);
var entityValidator = new EntityValidator(engine);

container.Register(Component.For<IEntityValidator>().Instance(entityValidator));

var behaviorStore = new BehaviorDictionary();
behaviorStore.For<Customer>()
.Add<NotifyPropertyChangedBehavior>()
.Add<DataErrorInfoBehavior>();
behaviorStore.For<CustomerWithNoInterface>()
.Add<NotifyPropertyChangedBehavior>()
.Add<DataErrorInfoBehavior>();


container.Register(Component.For<IBehaviorStore>().Instance(behaviorStore));

container.Register(Component.For<ICustomer>().ImplementedBy<Customer>().LifeStyle.Transient);

container.Register(Component.For<CustomerWithNoInterface>().LifeStyle.Transient);
}

[TestMethod]//FAILED
public void
ICustomer_PropertyChanged_WhenAssignPropertyFromInside_ShouldDispatched()
{
var isChanged = false;
var customer = container.Resolve<ICustomer>();
((SysCom.INotifyPropertyChanged)customer).PropertyChanged
+= (s, e) => { isChanged = true; };
customer.ChangeEmail();

Assert.IsTrue(isChanged);
}

[TestMethod]//PASS
public void
CustomerWithNoProxy_PropertyChanged_WhenAssignPropertyFromInside_ShouldDispatched()
{
var isChanged = false;
var customer =
container.Resolve<CustomerWithNoInterface>();
((SysCom.INotifyPropertyChanged)customer).PropertyChanged
+= (s, e) => { isChanged = true; };
customer.ChangeEmail();

Assert.IsTrue(isChanged);
}
}
}

José F. Romaniello

unread,
Oct 19, 2010, 5:16:08 PM10/19/10
to unha...@googlegroups.com
Thats the way interface proxies work.... I can't do anything to help you here.
when using interface-proxies you have two instances:
  -proxy implementing the interface (in your test ICustomer)
  -target of the real type, (in your test Customer..)

Dynamic proxy technologies such Castle, LinFu or Spring, can't do anything with calls being made inside the target.

Class proxies are a completely different thing, because you only have one instance, and all public methods of that instance are intercepted. The proxy inherits from the real class.
Castle support class proxies, but for instance LinFu treat them as interface proxy (two instances no matter you are providing only one class).

ktu...@gmail.com

unread,
Oct 19, 2010, 7:54:20 PM10/19/10
to uNhAddIns
Ok, so true that was the dynamic proxy behavior..
Thank you for your information.

On Oct 20, 5:16 am, José F. Romaniello <jfromanie...@gmail.com> wrote:
> Thats the way interface proxies work.... I can't do anything to help you
> here.
> when using interface-proxies you have two instances:
>   -proxy implementing the interface (in your test ICustomer)
>   -target of the real type, (in your test Customer..)
>
> Dynamic proxy technologies such Castle, LinFu or Spring, can't do anything
> with calls being made inside the target.
>
> Class proxies are a completely different thing, because you only have one
> instance, and all public methods of that instance are intercepted. The proxy
> inherits from the real class.
> Castle support class proxies, but for instance LinFu treat them as interface
> proxy (two instances no matter you are providing only one class).
>
> 2010/10/19 ktut...@gmail.com <ktut...@gmail.com>
Reply all
Reply to author
Forward
0 new messages