Thanks,  I got it working.

Quite a few of my ViewModels consume the factory to generate other
ViewModels, so 1 isn't really an option.

This didn't work and I would have ended up littering my factory with lots
of similar methods if it had:

    TemplateEditViewModelCommands
CreateTemplateEditViewModelCommands(TemplateEditViewModel
mismatchedArgumentName);

Whilst this did (if the resolved object has a constructor that has an
argument called parentModel that is of a type inherited from ViewModelBase).

   T CreateViewModel<T>(ViewModelBase parentModel) where T : ViewModelBase;

So Windsor in my case is failing to match by exact type (I'm using 2.5.3).
 My test projects used the same argument names, so I solved my problem
unknowingly.

Matt

I got it working
2011/12/21 Krzysztof Koźmic <[email protected]>

>  The problem is your signatures don't match.
>
> Windsor will try to match inline dependencies by name and then if that
> fails by (exact) type.
>
> Your factory defines the argument as
>
> ViewModelBase parentModel
>
> but the TemplateEditViewModelCommands defines its dependency as
>
> TemplateEditViewModel parentViewModel
>
> As you can see, neither is matching therefore Windsor will not use the
> agument you're providing, trying to get the dependency from the container
> itself, which it's also unable to do, because that'd cause a cycle, hence
> the exception.
>
> Two solutions to that:
> 1. don't abuse factories - pass the dependency right into the object
> rather than using factory in the constructor.
> 2. Make sure the names and/or types align between the factory and the
> TemplateEditViewModelCommands
>
>
> K
>
>
> On 22/12/2011 12:22 AM, Matthew Slane wrote:
>
> Hi,
>
>  I can't really break the cycle as I can't see why it should be cyclic.
>
>  I set my app up like so in the constructor of the main window.
>
>              _container = new WindsorContainer();
>
>              _container.Install(
>                 FromAssembly.Containing<TemplateEngineViewModel>()
>                 );
>
>              this.DataContext =
> _container.Resolve<TemplateEngineViewModel>();
>
>  Ctor of TemplateEngineViewModel:
>
>          public TemplateEngineViewModel(IViewModelFactory factory)
>         {
>             _factory = factory;
>             _editorViewModel =
> _factory.CreateViewModel<TemplateEditViewModel>();
>         }
>
>  Ctor of TemplateEditViewModel:
>
>           public TemplateEditViewModel(IViewModelFactory factory)
>         {
>             _factory = factory;
>             _commands =
> _factory.CreateViewModel<TemplateEditViewModelCommands>(this); //fails
> here, "this" doesn't get respected, a new instance of TemplateEditViewModel
> gets created instead.
>         }
>
>  and then:
>
>       public TemplateEditViewModelCommands(TemplateEditViewModel
> parentViewModel, IViewModelFactory factory)
>       {
>              _parent = parentViewModel;
>             _factory = factory;
>       }
>
>  my Installer is simply.
>
>              IFacility[] facilities = container.Kernel.GetFacilities();
>             if(facilities.Where(x => x.GetType() ==
> typeof(TypedFactoryFacility)).Count() == 0)
>                         container.AddFacility<TypedFactoryFacility>();
>
>              container.Register(
>                    Component.For<IViewModelFactory>().AsFactory()
>                     AllTypes.FromThisAssembly().BasedOn<ViewModelBase>()
>                 );
>
>  The error message is:
>
>  Castle.MicroKernel.CircularDependencyException was unhandled by user code
>   Message=A cycle was detected when trying to resolve a dependency. The
> dependency graph that resulted in a cycle is:
>  - Service dependency 'parentViewModel' type
> 'TemplateEngineGUILib.ViewModels.EditViewModel' for Void
> .ctor(TemplateEngineGUILib.ViewModels.TemplateEditViewModel,
> TemplateEngineGUILib.IViewModelFactory) in type
> TemplateEngineGUILib.ViewModels.TemplateEditViewModelCommands
>  + Service dependency 'parentViewModel' type
> 'ExcelTemplateEngineGUILib.ViewModels.TemplateEditViewModel' for Void
> .ctor(TemplateEngineGUILib.ViewModels.TemplateEditViewModel,
> TemplateEngineGUILib.IViewModelFactory) in
> TemplateEngineGUILib.ViewModels.TemplateEditViewModelCommands
>
>  As I said, if I take all these constructors and create new classes
> around them in a new project with the same configuration, it works fine.
>
>  Thanks,
>
>  Matt
>
> 2011/12/21 Krzysztof Koźmic <[email protected]>
>
>> Matt,
>>
>> First of all inspect what the cycle is, and why it appears. Can you break
>> it?
>>
>> If not, think about what would you do differently if you were building
>> the graph by hand.
>>
>> If you then can share those details we will be able to assist you further.
>>
>> cheers,
>>  Krzysztof
>>
>>
>> On 21/12/2011 10:38 PM, Matt wrote:
>>
>>> Hi,
>>>
>>> I'm struggling to resolve a circular dependency issue.  I'm using
>>> Castle to resolve view models in an MVVM project and some view models
>>> have a child parent relationship.  All my view models inherit from
>>> ViewModelBase.
>>>
>>> I have a factory interface:
>>>
>>> public interface IViewModelFactory
>>> {
>>>         T CreateViewModel<T>() where T : ViewModelBase;
>>>         T CreateViewModel<T>(ViewModelBase parentModel) where T :
>>> ViewModelBase;
>>> }
>>>
>>> I have a basic installer which simply registers the factory interface
>>> and also all types based on ViewModelBase
>>>
>>> Every time I try to call something like
>>>
>>> var commands =
>>> factory.CreateViewModel<TemplateCommandsViewModel>(this);
>>>
>>> I get a circular dependency exception.
>>>
>>> However when I stripped the code down to purely the IOC stuff and
>>> moved it to a different project it works fine.
>>>
>>> When I watch the constructors in the debugger, instead of passing
>>> "this" through to the constructor, a new instance is created.
>>>
>>> Being relatively new to Castle, I am absolutely clueless as to where
>>> to start on this one.  Any ideas?
>>>
>>> Thanks,
>>>
>>> Matt
>>>
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Castle Project Users" group.
>> To post to this group, send email to
>> [email protected].
>> To unsubscribe from this group, send email to
>> [email protected].
>> For more options, visit this group at
>> http://groups.google.com/group/castle-project-users?hl=en.
>>
>>
>  --
> You received this message because you are subscribed to the Google Groups
> "Castle Project Users" group.
> To post to this group, send email to [email protected]
> .
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/castle-project-users?hl=en.
>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Castle Project Users" group.
> To post to this group, send email to [email protected]
> .
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/castle-project-users?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-users?hl=en.

Reply via email to