简体   繁体   English

理解抽象工厂模式中的代码

[英]Understanding the code in an Abstract factory pattern

I am trying to learn design patterns in C# and my friend has written me some code for an Abstract factory pattern (I think).我想在 C# 学习设计模式,我的朋友给我写了一些抽象工厂模式的代码(我认为)。

from what I am seeing the code creates a factory(Fa), this factory(Fa) then creates another factory(Fb) based on an Enum and then that factory(Fb) creates a concrete class that can be used to call an API etc.从我所看到的代码创建一个工厂(Fa),这个工厂(Fa)然后创建另一个基于枚举的工厂(Fb)然后那个工厂(Fb)创建一个具体的 class 可用于调用 API 等.

I can create a factory(Fb) and it creates the class but when I call methods from the class that were created by the factory(fb), I do not see my methods and cant call them but can only call the class that it inherits.我可以创建一个工厂 (Fb) 并创建 class 但是当我从工厂 (fb) 创建的 class 调用方法时,我看不到我的方法并且无法调用它们但只能调用它继承的 class .

What I am trying to do in a nutshell, is create a factory that creates Jane dolls (like it does) and this inherits everything from the doll class, it also has all its own properties, great, but why cant I access its own properties when I make a factory to create the Jane Factory, it only lets me use the inherited Doll methods this way, but if I created another factory to create Santa dolls it would have different methods I need to use.简而言之,我想做的是创建一个工厂来创建 Jane 娃娃(就像它所做的那样),它继承了娃娃 class 的所有内容,它也有自己的所有属性,很好,但为什么我不能访问它自己的属性当我创建一个工厂来创建 Jane Factory 时,它只允许我以这种方式使用继承的 Doll 方法,但如果我创建另一个工厂来创建圣诞老人玩偶,它就会有我需要使用的不同方法。

**Web.Controllers ** **网络控制器**

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;


namespace Qqq.Dolls.Web.Controllers
{

    public class InventoryController : Controller
    {
        private readonly IDollFactory _dollFactory;
        private readonly IJaneDollFactory _janeDollFactory;
        private readonly IMapper _mapper;

        public InventoryController(IJaneDollFactory dollFactory, IMapper mapper, IDollFactory dollFactory1)
        {
            _janeDollFactory = dollFactory;
            _mapper = mapper;
            _dollFactory = dollFactory1;
        }

        public async Task<IActionResult> List()
        {
            var token = HttpContext.Session.GetObject<OAuthResponse>(SessionConstants.JaneToken);
            var doll = _JaneDollFactory.Create(token, JaneScopeConstants.GetAllScopes());


            var a = _DollFactory.Create(Doll.Jane, HttpContext);

            var ab = await a.LGetProductAsync("TestProduct");


            var inventory = await doll.GetInventory();

            var ret = inventory.InventoryItems.Select(
                inventoryItem => _mapper.Map<InventoryViewModel>(inventoryItem));

            return View(ret);

        }
    }

}

DollFactory人偶工厂

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Qqq.Dolls.Web.Infrastructure;

public class DollFactory : IDollFactory
{
    private readonly IJaneDollFactory _JaneDollFactory;

    public DollFactory(IJaneDollFactory JaneDollFactory)
    {
        _JaneDollFactory = JaneDollFactory;
    }

    public IDoll Create(Doll Doll, HttpContext httpContext)
    {
        switch (Doll)
        {
            case Doll.Jane:
                var token = httpContext.Session.GetObject<OAuthResponse>(SessionConstants.JaneToken);

                return _JaneDollFactory.Create(token, JaneScopeConstants.GetAllScopes());
            default:
                throw new NotImplementedException();
        }

    }
}

IJaneDollFactory Interface IJaneDollFactory 接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Qqq.Dolls.Jane;

public interface IJaneDollFactory
{
    IJaneDoll Create(OAuthResponse oAuthResponse, List<string> scopes, HttpMessageHandler httpMessageHandler = null);
}

**IJaneDoll interface ** **IJaneDoll 界面**

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Qqq.Dolls.Jane;

public interface IJaneDoll : IDoll
{
    //Inventory
    Task<Inventory> GetInventory();
    Task ListInventoryItem(InventoryItem product);
    Task DeleteInventoryItem(string sku);

}

IDoll interface玩偶界面

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

public interface IDoll
{
    Task ListProductAsync(Product product);

    Task<Product> GetProductAsync(string productId);
}

interface IDollFactory接口 IDollFactory

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Qqq.Dolls.Web.Infrastructure;

public interface IDollFactory
{
    IDoll Create(Doll doll, HttpContext httpContext);
}

JaneDollFactory简娃娃工厂

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;


namespace Qqq.Dolls.Jane;

public class JaneDollFactory : IJaneDollFactory
{
    private readonly IMapper _mapper;
    private readonly JaneApiConfiguration _JaneApiConfiguration;

    public JaneDollFactory(IOptions<JaneApiConfiguration> JaneApiConfiguration, IMapper mapper)
    {
        _mapper = mapper;
        _JaneApiConfiguration = JaneApiConfiguration.Value;
    }
    public IJaneDoll Create(OAuthResponse oAuthResponse, List<string> scopes, HttpMessageHandler httpMessageHandler = null)
    {
        return new JaneDoll(_mapper, _JaneApiConfiguration, oAuthResponse, scopes, httpMessageHandler);
    }

}

This is happening is because in you factory create method you have the return type as发生这种情况是因为在您的工厂创建方法中,您的返回类型为

IDoll偶像

So when you create a doll, no matter what doll you instantiate, it gets implicitly casted into an IDoll (this is the mistake in DollFactory class)所以当你创建一个娃娃时,无论你实例化什么娃娃,它都会被隐式地转换成一个 IDoll(这是 DollFactory 类中的错误)

Since your caller knows what doll it wants the abstract factory to create, when you retrieve the object you can explicitly cast it to an IJaneDoll由于您的调用者知道它希望抽象工厂创建什么玩偶,因此当您检索 object 时,您可以将其显式转换为 IJaneDoll

var a = (IJaneDoll) _DollFactory.Create(Doll.Jane, HttpContext);

This should allow you to access members from both IDoll and IJane doll.这应该允许您访问 IDoll 和 IJane doll 的成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM