Frage

Ich habe gerade James Kovac Artikel über Inversion of Control und Dependency Injection abgeschlossen und dann verwendet, was ich gelernt, mein eigenes IoC / DI Beispiel unten zu machen.

Ich bin ganz satisified mit diesem Beispiel, da es:

  • erfüllt die Testbarkeit Aspekt von IoC, dass es Kunden, sowohl instanziiert ein Repository, indem und eine MockRepository
  • auch die Authorization Service entkoppelt , die Sie erlauben würde, z.B. ein weiteren Authorization Service mit unterschiedlichen Regeln schreiben, und dann könnte man sich leicht aus tauschen basierend auf anderen Bedingungen

Dennoch, mit Blick in Richtung von hier voran, scheinen einige Dinge seltsam:

  • Ich scheine nicht einen "Container" zu haben, . Ist meine Customer-Klasse in diesem Sinne „als Container handeln“?
  • wenn ich in den Hafen dieser zu WPF waren, Dabei würde Module (im Sinne von Prism) in diesem Beispiel passen (zum Beispiel würde AuthorizationService und Repository sein Module?)
  • wenn ich in dem Hafen, dies zu WPF war, wo würde MVVM passen ? haben Sie haben Teile von MVVM durch die Abhängigkeit Injektion oder MVVM etwas getrennt zusammen.

Vielen Dank für jede Richtung, die Sie auf diese liefern kann.

NEW CODE AUF DER GRUNDLAGE KOMMENTAR:

using System;
using System.Linq;
using System.Collections.Generic;

namespace TestSimpleDependencyInjection1
{
    class Program
    {
        static void Main(string[] args)
        {
            AuthorizationService authorizationService = new AuthorizationService();

            //real example
            Repository repository = new Repository(authorizationService);
            for (int id = 1; id <= 3; id++)
            {
                Customer customer = repository.GetCustomer(id);
                customer.Display();
            }
            Console.WriteLine();

            //mock test example
            MockRepository mockRepository = new MockRepository(authorizationService);
            Customer mockCustomerAdministrator = repository.GetCustomer(1);
            Customer mockCustomerSalesperson = repository.GetCustomer(2);
            UnitTester.Assert("Administrators have access", mockCustomerAdministrator.GetAuthorizationMessage(), "Access Granted");
            UnitTester.Assert("Salespeople do not have access", mockCustomerAdministrator.GetAuthorizationMessage(), "Access Granted");

            Console.ReadLine();
        }
    }

    public static class UnitTester
    {
        public static void Assert(string title, string value, string expectedResult)
        {
            Console.WriteLine(value == expectedResult ? String.Format("{0}: test succeeded", title) : String.Format("{0}: TEST FAILED!", title));
        }
    }

    public class Customer
    {

        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public AccessGroup AccessGroup { get; set; }
        public AuthorizationService AuthorizationService { get; set; }

        public string GetAuthorizationMessage()
        {
            return this.AuthorizationService.GetAccessMessage(this);
        }

        public Customer()
        {

        }

        public void Display()
        {
            Console.WriteLine("Customer: {1}, {0} ({2}): {3}", this.FirstName, this.LastName, this.AccessGroup, this.GetAuthorizationMessage());
        }
    }

    public class AuthorizationService
    {
        public string GetAccessMessage(Customer customer)
        {
            return customer.AccessGroup == AccessGroup.Administrator ? "Access Granted" : "Access Denied";
        }
    }


    public class Repository : IRepository
    {
        private List<Customer> _customerSet = new List<Customer>();
        private AuthorizationService _authorizationService;

        public Repository(AuthorizationService authorizationService)
        {
            _authorizationService = authorizationService;
            _customerSet.Add(new Customer {AuthorizationService = _authorizationService, ID = 1, FirstName = "Jim", LastName = "Smith", AccessGroup = AccessGroup.Administrator });
            _customerSet.Add(new Customer {AuthorizationService = _authorizationService, ID = 2, FirstName = "John", LastName = "Johnson", AccessGroup = AccessGroup.Administrator });
            _customerSet.Add(new Customer {AuthorizationService = _authorizationService, ID = 3, FirstName = "Hank", LastName = "Rivers", AccessGroup = AccessGroup.Salesperson });
        }

        public Customer GetCustomer(int id)
        {
            return (from c in _customerSet
                    where c.ID == id
                    select c).SingleOrDefault();
        }
    }

    public class MockRepository : IRepository
    {
        private List<Customer> _customerSet = new List<Customer>();
        private AuthorizationService _authorizationService;

        public MockRepository(AuthorizationService authorizationService)
        {
            _authorizationService = authorizationService;
            _customerSet.Add(new Customer { AuthorizationService = _authorizationService, ID = 1, FirstName = "Test1AdministratorFirstName", LastName = "Test1AdministratorLastName", AccessGroup = AccessGroup.Administrator });
            _customerSet.Add(new Customer { AuthorizationService = _authorizationService, ID = 2, FirstName = "Test2SalespersonFirstName", LastName = "Test2SalesPersonLastName", AccessGroup = AccessGroup.Salesperson });
        }

        public Customer GetCustomer(int id)
        {
            return (from c in _customerSet
                            where c.ID == id
                            select c).SingleOrDefault();
        }

    }

    public interface IRepository
    {
        Customer GetCustomer(int id);
    }

    public enum AccessGroup
    {
        Administrator,
        Salesperson
    }
}

UND PER REQUEST, IST HIER DER ORIGINAL CODE:

using System;
using System.Collections.Generic;

namespace TestSimpleDependencyInjection1
{
    class Program
    {
        static void Main(string[] args)
        {
            AuthorizationService authorizationService = new AuthorizationService();

            //real example
            Repository repository = new Repository();
            for (int id = 1; id <= 3; id++)
            {
                Customer customer = new Customer(id, authorizationService, repository);
                customer.Display();
            }
            Console.WriteLine();

            //mock test example
            MockRepository mockRepository = new MockRepository();
            Customer mockCustomerAdministrator = new Customer(1, authorizationService, mockRepository);
            Customer mockCustomerSalesperson = new Customer(2, authorizationService, mockRepository);
            UnitTester.Assert("Administrators have access", mockCustomerAdministrator.GetAuthorizationMessage(), "Access Granted");
            UnitTester.Assert("Salespeople do not have access", mockCustomerAdministrator.GetAuthorizationMessage(), "Access Granted");

            Console.ReadLine();
        }
    }

    public static class UnitTester
    {
        public static void Assert(string title, string value, string expectedResult)
        {
            Console.WriteLine(value == expectedResult ? String.Format("{0}: test succeeded", title) : String.Format("{0}: TEST FAILED!", title));
        }
    }

    public class Customer
    {
        private AuthorizationService authorizationService;
        private IRepository repository;

        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public AccessGroup AccessGroup { get; set; }

        public string GetAuthorizationMessage()
        {
            return authorizationService.GetAccessMessage(this);
        }

        public Customer(int id, AuthorizationService authorizationService, IRepository repository)
        {
            this.authorizationService = authorizationService;
            this.repository = repository;

            CustomerDB customerDB = repository.GetCustomerDB(id);
            this.ID = customerDB.ID;
            this.FirstName = customerDB.FirstName;
            this.LastName = customerDB.LastName;
            this.AccessGroup = customerDB.AccessGroup;
        }

        public void Display()
        {
            Console.WriteLine("Customer: {1}, {0} ({2}): {3}", this.FirstName, this.LastName, this.AccessGroup, this.GetAuthorizationMessage());
        }
    }

    public class AuthorizationService
    {
        public string GetAccessMessage(Customer customer)
        {
            return customer.AccessGroup == AccessGroup.Administrator ? "Access Granted" : "Access Denied";
        }
    }


    public class Repository : IRepository
    {
        private List<CustomerDB> _customerDBSet = new List<CustomerDB>();

        public Repository()
        {
            _customerDBSet.Add(new CustomerDB { ID = 1, FirstName = "Jim", LastName = "Smith", AccessGroup = AccessGroup.Administrator });
            _customerDBSet.Add(new CustomerDB { ID = 2, FirstName = "John", LastName = "Johnson", AccessGroup = AccessGroup.Administrator });
            _customerDBSet.Add(new CustomerDB { ID = 3, FirstName = "Hank", LastName = "Rivers", AccessGroup = AccessGroup.Salesperson });
        }

        public CustomerDB GetCustomerDB(int id)
        {
            CustomerDB customerDBchosen = null;
            //this should be done with LINQ (couldn't get it CustomerDB to implement IEnumerable correctly)
            foreach (CustomerDB customerDB in _customerDBSet)
            {
                if (customerDB.ID == id)
                {
                    customerDBchosen = customerDB;
                    break;
                }
            }
            return customerDBchosen;
        }
    }

    public class MockRepository : IRepository
    {
        public CustomerDB GetCustomerDB(int id)
        {
            switch (id)
            {
                case 1:
                    return new CustomerDB { ID = 1, FirstName = "Test1AdministratorFirstName", LastName = "Test1AdministratorLastName", AccessGroup = AccessGroup.Administrator };
                case 2:
                    return new CustomerDB { ID = 2, FirstName = "Test2SalespersonFirstName", LastName = "Test2SalesPersonLastName", AccessGroup = AccessGroup.Salesperson };
                default:
                    return null;
            }
        }
    }

    public interface IRepository
    {
        CustomerDB GetCustomerDB(int id);
    }

    public class CustomerDB
    {
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public AccessGroup AccessGroup { get; set; }
    }

    public enum AccessGroup
    {
        Administrator,
        Salesperson
    }
}
War es hilfreich?

Lösung

Ihr Code verstößt gegen das einzige Verantwortung Haupt in einem ziemlich ernsthaft.

http://en.wikipedia.org/wiki/Single_responsibility_principle

Ihr Customer-Objekt sollte sich nicht von einem Repository werden geladen, sollte das Repository das Customer-Objekt werden geladen und es zurück an den Aufrufer übergeben.

würde ich erwarten, etwas mehr wie:

Customer customer = repository.GetCustomer(3);

Andere Tipps

Nutzung von Switch-Anweisungen in den meisten Fällen verletzen SRP. Hat check this out nach Möglichkeiten, switch-Anweisungen in Ihrem Code zu beseitigen. Die Herausforderung und Schönheit von lose gekoppelten Code zu schreiben ist, wenn, wenn sonst zu beseitigen und Aussagen wechseln.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top