Gorkhali Ответов: 1

Инжекция интерфейсов в класс WPF


I am trying to show main window after successful login.I used interface as parameter to constructor in main window. Now when I try showing main window, I get an error because I cannot pass interface as parameter to main window.I saw many posts like mine but I thought it is quite different from them.

This is my main window constructor:

    <pre>public Home_Page(IGetAllItemClass clas)
            {
                InitializeComponent();
                _allClass = clas;
            }
            IGetAllItemClass _allClass;


Мой код в окне входа в систему, откуда мне нужно показать основную форму:

Home_Page h = new Home_Page();
     h.ShowDialog();

Мое приложение. xaml:

<Application x:Class="Cafe_WPF.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:Cafe_WPF"
                 Startup="App_Startup">
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="scroll_style.xaml" />
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    </Application>


Это мое приложение. cs :


<pre>public partial class App : Application
        {
            void App_Startup(object sender, StartupEventArgs e)
            {
                #region login_dependencies
                var container = new UnityContainer();
                container.RegisterType<IGetIP, get_ip_address>();
                container.RegisterType<IUserDetails, get_user_details>();
              container.RegisterType<IgetBusinessDetailsFromPosId, get_business_info_from_pos>();
                #endregion
                #region home_page_dependencies
                var home = new UnityContainer();
                container.RegisterType<IGetAllItemClass, get_all_item_class>();
                Home_Page hm = home.Resolve<Home_Page>();
                #endregion
                Login_Window lg = container.Resolve<Login_Window>();
                lg.ShowDialog();
            }
        }


Это мой интерфейс:

namespace Cafe_WPF.Interface
    {
      public interface IGetAllItemClass
        {
            DataTable item_class(string business_info_id, string rvc_id);
        }
    }


И мой интерфейс реализации сервиса класса:

class get_all_item_class : IGetAllItemClass
    {
        public DataTable item_class(string business_info_id, string rvc_id)
        {
            try
            {
                string sql = //query
                return CafePOS.Library.DataAccessLayer.Instance.ExecuteQuery(sql);
    
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

Я пытаюсь использовать инъекцию зависимостей.Может быть, я что-то упускаю. Кто-нибудь может мне в этом помочь ? Я застрял на этом.





Что я уже пробовал:

Вышеприведенные коды - это то,что я пробовал.Может быть, я неправильно воспринимаю архитектуру

Kornfeld Eliyahu Peter

Но конструктор в первой части никогда не будет вызван...
public Home_Page (IGetAllItemClass clas)!!! но новый Home_Page ()!!! Который вызовет конструктор по умолчанию (без параметров) или потерпит неудачу...

Gorkhali

Я тоже имел это в виду, сэр. Как я могу вызвать параметризованный конструктор ?Если я вызываю интерфейс из окна входа в систему, есть ли какой-то смысл иметь инъекцию зависимостей? Как я могу назвать эту домашнюю страницу?

Kornfeld Eliyahu Peter

Вы получили свое решение 16 часов назад! Читай!

Gorkhali

Я прочитал его и сделал то же самое.Не могли бы вы прочитать комментарий под этим ответом и помочь мне в этом? Спасибо.

1 Ответов

Рейтинг:
11

Richard Deeming

Цитата:
Home_Page h = new Home_Page();

Вы не можете назвать это так, потому что Home_Page класс не имеет конструктора без параметров. Вам нужно передать в экземпляр IGetAllItemClass интерфейс.

Самым простым решением является импорт Home_Page экземпляр в качестве параметра конструктора вашего Login_Window класс:
private readonly Home_Page _homePage;

public Login_Window(..., Home_Page homePage)
{
    ...
    _homePage = homePage;
}

public void ShowHomePage()
{
    _homePage.ShowDialog();
}

Таким образом, вы используете экземпляр, созданный контейнером Unity, а не пытаетесь создать новый экземпляр вручную.


Gorkhali

- Спасибо, сэр.Я застрял на нем на несколько дней. В то же время у меня есть небольшая путаница. Таким образом, мне нужно импортировать экземпляр каждой формы, которую я должен показать? Не могли бы вы мне объяснить? Или если я ошибаюсь в своей архитектуре приложения или архитектуре реализации Unity?

Richard Deeming

Вам нужно либо импортировать экземпляр каждой формы, либо импортировать зависимости, необходимые для создания каждой формы.

Лучшим подходом было бы создать фабрику для каждой формы, где реализация импортирует необходимые зависимости. Затем вы импортируете фабрику для каждой формы, которую вам нужно показать.

public interface IHomePageFactory
{
    Home_Page Create();
}

public class HomePageFactory
{
    public HomePageFactory(IGetAllItemClass getAllItems)
    {
        GetAllItems = getAllItems;
    }
    
    public IGetAllItemClass GetAllItems { get; }
    
    public Home_Page Create()
    {
        return new Home_Page(GetAllItems);
    }
}

public class Login_Window
{
    public Login_Window(IHomePageFactory homePageFactory)
    {
        HomePageFactory = homePageFactory;
    }
    
    public IHomePageFactory HomePageFactory { get; }
    
    public void ShowHomePage()
    {
        Home_Page h = HomePageFactory.Create();
        h.ShowDialog();
    }
}

var container = new UnityContainer();
container.RegisterType<IGetAllItemClass, get_all_item_class>();
container.RegisterType<IHomePageFactory, HomePageFactory>();

Login_Window lg = container.Resolve<Login_Window>();
lg.ShowDialog();