How to do simple catel dependency injection

I'am learning catel mvvm framework, and have some understanding trouble. Trying build simple project, very simple, using catel framework. Have a model

    public class First : ModelBase
{
    public String FirstValue
    {
        get { return GetValue<String>(FirstValueProperty); }
        set { SetValue(FirstValueProperty, value); }
    }

    public static readonly PropertyData FirstValueProperty = RegisterProperty("FirstValue", typeof(String), "First Text");

    public String SecondValue
    {
        get { return GetValue<String>(SecondValueProperty); }
        set { SetValue(SecondValueProperty, value); }
    }

    public static readonly PropertyData SecondValueProperty = RegisterProperty("SecondValue", typeof(String), "Second text");
}

Then have viewmodel

 public class FirstViewModel : ViewModelBase
{
    public FirstViewModel(First first)
    {
        Argument.IsNotNull(() => first);

        First = first;
    }

    [Model]
    public First First
    {
        get { return GetValue<First>(TestModelProperty); }
        private set { SetValue(TestModelProperty, value); }
    }
    public static readonly PropertyData TestModelProperty = RegisterProperty("TestModel", typeof(First));

    [ViewModelToModel("First")]
    public String FirstValue
    {
        get { return GetValue<String>(FirstValueProperty); }
        set { SetValue(FirstValueProperty, value); }
    }
    public static readonly PropertyData FirstValueProperty = RegisterProperty("FirstValue", typeof(String));

    [ViewModelToModel("First")]
    public String SecondValue
    {
        get { return GetValue<String>(SecondValueProperty); }
        set { SetValue(SecondValueProperty, value); }
    }
    public static readonly PropertyData SecondValueProperty = RegisterProperty("SecondValue", typeof(String));
}

At last have service

public class FirstService : IFirstService
{
    public First Read()
    {
        return new First();
    }

    public First Write(First first)
    {
       first.SecondValue = first.FirstValue;
        return first;
    }
}

Using view

<catel:StackGrid>
        <catel:StackGrid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </catel:StackGrid.RowDefinitions>
        <catel:StackGrid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </catel:StackGrid.ColumnDefinitions>
        <Label Content="First value" />
        <TextBox Text="{Binding FirstValue}" TextAlignment="Center" Width="100"/>
        <Label Content="Second value" />
        <TextBox Text="{Binding FirstSecond}" TextAlignment="Center" Width="100"/>
    </catel:StackGrid>

And window

<catel:StackGrid x:Name="LayoutRoot">
    <catel:StackGrid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </catel:StackGrid.RowDefinitions>
    <Label Content="{Binding Title}" />
    <views:FirstView />
    <Button Content="Write" Command="{Binding WriteFirst}" Width="70" />
</catel:StackGrid>

How to do sipmle catel dependency injection, that on start application in both textboxes was default data from First class. And how by pressing Write button copy someone entering in first textbox to second textbox through using service. I'm tried to do this by example Getting started from catel documentation. But don't work.

Upvotes: 0

Views: 291

Answers (1)

Max
Max

Reputation: 143

first of all you can use Catel.Fody nuget package which will let you to simplify your code:

public class FirstModel : ModelBase
{
     public String FirstValue { get; set; }
     public String SecondValue { get; set; }
}

public class FirstViewModel : ViewModelBase
{
     private readonly IFirstService _firstService;

     public FirstViewModel(IFirstService firstService)
         : this(new First(), firstService)
     {

     }

     public FirstViewModel(First first, IFirstService firstService)
     {
         Argument.IsNotNull(() => first);
         Argument.IsNotNull(() => firstService);

         _firstService = firstService;
         First = first;

         WriteFirst = new Command(OnWriteFirstExecute);
     }

     [Model]
     // you can use ExposeAttribute if you don't want to use 'FirstValue'
     // property inside of ViewModel and only want to use it for binding
     [Expose(nameof(FirstModel.FirstValue))]
     public FirstModel First { get; set; }

     [ViewModelToModel(nameof(First)]
     public String SecondValue { get; set; }

     public Command WriteFirst { get; }

     private void OnWriteFirstExecute()
     {
         // here you can put you logic (not sure what you want to achieve)
         // _firstService.Write()
     }
}

if you want to use dependency injection, you have to register you service anywhere in code before first injection. For example you can do that in App.xaml.cs or you can use ModileInit.Fody nuget package and register all your services in ModuleInitializer.cs

var serviceLocator = this.GetServiseLocator();
// or instatic context you can use:
// var serviceLocator = ServiceLocator.Default;
serviseLocator.RegisterType<IFirstService, FirstService>();

Another important thing is you have to use one ViewModel per each View so I don't really undersatand you in that part. Just try to put you xaml into single file (in your case I think it is window)

Upvotes: 1

Related Questions