C# 实体原则的重构

C# 实体原则的重构,c#,solid-principles,C#,Solid Principles,在阅读了一本书和一篇在线文章中有关SOLID代码的内容后,我想重构一个现有的类,使其能够“SOLID”兼容 但我想我迷路了,尤其是在依赖项注入方面:当我想实例化类的一个对象时,我需要“注入”所有依赖项,但依赖项本身有依赖项。。这就是我开始迷路的地方 想法是这样的:我想创建一个类(在我的例子中,是一个简单的AmazonS3包装类)来di简单的上传和获取URL操作 如何正确使用接口和依赖项注入?出了什么问题? 这个班应该是什么样子 这是我的密码: public interface IConfigur

在阅读了一本书和一篇在线文章中有关SOLID代码的内容后,我想重构一个现有的类,使其能够“SOLID”兼容

但我想我迷路了,尤其是在依赖项注入方面:当我想实例化类的一个对象时,我需要“注入”所有依赖项,但依赖项本身有依赖项。。这就是我开始迷路的地方

想法是这样的:我想创建一个类(在我的例子中,是一个简单的AmazonS3包装类)来di简单的上传和获取URL操作

如何正确使用接口和依赖项注入?出了什么问题? 这个班应该是什么样子

这是我的密码:

public interface IConfigurationProvider
{
    string GetConfigurationValue(String configurationKey);
}

public interface ILogger
{
    void WriteLog(String message);
}

public interface IAWSClientProvider
{
    AmazonS3Client GetAmazonS3Client();
}

public interface IAWSBucketManager
{
    string GetDefaultBucketName();
}

public class AWSBucketManager : IAWSBucketManager
{
    ILogger logger;
    IConfigurationProvider configurationProvider;

    public AWSBucketManager(ILogger Logger, IConfigurationProvider ConfigurationProvider)
    {
        logger = Logger;
        configurationProvider = ConfigurationProvider;
    }

    public string GetDefaultBucketName()
    {
        string bucketName = string.Empty;

        try
        {
            bucketName = configurationProvider.GetConfigurationValue("Amazon_S3_ExportAds_BucketName");
        }
        catch (Exception ex)
        {
            logger.WriteLog(String.Format("getBucketName : Unable to get bucket name from configuration.\r\n{0}", ex));
        }

        return bucketName;
    }
}

public class AWSClientProvider : IAWSClientProvider
{
    IConfigurationProvider configurationProvider;
    IAWSBucketManager awsBucketManager;
    ILogger logger;

    private string awsS3BucketName;
    private Dictionary<string, RegionEndpoint> regionEndpoints;

    public AWSClientProvider(IConfigurationProvider ConfigurationProvider, IAWSBucketManager BucketManager, ILogger Logger)
    {
        logger = Logger;
        configurationProvider = ConfigurationProvider;
        awsBucketManager = BucketManager;
    }

    private RegionEndpoint getAWSRegion()
    {
        RegionEndpoint regionEndpoint = null;
        // Init endpoints dictionary
        try
        {
            IEnumerable<RegionEndpoint> regions = RegionEndpoint.EnumerableAllRegions;
            regionEndpoints = regions.ToDictionary(r => r.SystemName, r => r);
        }
        catch (Exception Ex)
        {
            logger.WriteLog(String.Format("getAWSRegion() - Failed to get region list from AWS.\r\n{0}", Ex));
            throw;
        }
        // Get configuration value
        try
        {
            string Config = configurationProvider.GetConfigurationValue("Amazon_S3_Region");
            if (String.IsNullOrEmpty(Config))
            {
                throw new Exception("getAWSRegion() : Amazon_S3_Region must not be null or empty string.");
            }

            regionEndpoint = regionEndpoints[Config];
        }
        catch (Exception Ex)
        {
            logger.WriteLog(String.Format("getAWSRegion() : Unable to get region settings from configuration.\r\n{0}", Ex));
            throw Ex;
        }

        return regionEndpoint;
    }

    private AWSCredentials getAWSCredentials()
    {
        string accessKey, secretKey;
        BasicAWSCredentials awsCredentials;

        try
        {
            accessKey = configurationProvider.GetConfigurationValue("Amazon_S3_AccessKey");
            secretKey = configurationProvider.GetConfigurationValue("Amazon_S3_SecretKey");
        }
        catch (Exception Ex)
        {
            logger.WriteLog(String.Format("getAWSCredentials() - Unable to get access key and secrey key values from configuration.\r\n", Ex.Message));
            throw;
        }

        try
        {
            awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
        }
        catch (Exception Ex)
        {
            logger.WriteLog(String.Format("getAWSCredentials() - Unable to create basic AWS credentials object.\r\n{0}", Ex.Message));
            awsCredentials = null;
            throw;
        }

        return awsCredentials;
    }

    public AmazonS3Client GetAmazonS3Client()
    {
        AmazonS3Client client = null;
        RegionEndpoint region = getAWSRegion();
        AWSCredentials credentials = getAWSCredentials();
        awsS3BucketName = awsBucketManager.GetDefaultBucketName();

        if (credentials != null)
        {
            client = new AmazonS3Client(credentials, region);
        }
        return client;
    }
}

public class AWSS3Actions
{
    IConfigurationProvider configurationProvider;       // decoupling getting configuration
    ILogger logger;                                     // decoupling logger
    IAWSClientProvider awsClientProvider;

    private const int defaultExpirationDays = 14;

    public AWSS3Actions(IConfigurationProvider ConfigurationProvider, ILogger Logger, IAWSClientProvider ClientProvider)
    {
        configurationProvider = ConfigurationProvider;
        logger = Logger;
        awsClientProvider = ClientProvider;
    }

    #region Private Mmethods

    private string getFileUrl(string fileName, int expirationDaysPeriod, string awsS3BucketName)
    {
        GetPreSignedUrlRequest request = new GetPreSignedUrlRequest();
        string URL = "";

        DateTime dtBase = new DateTime();
        dtBase = DateTime.Now;
        dtBase = dtBase.AddDays(expirationDaysPeriod);

        request.BucketName = awsS3BucketName;
        request.Key = fileName;
        request.Expires = dtBase;

        try
        {
            URL = awsClientProvider.GetAmazonS3Client().GetPreSignedURL(request);
        }
        catch (AmazonS3Exception ex)
        {
            // log
            logger.WriteLog(String.Format("getFileUrl() : Could not get presigned URL for the provided request.\r\n{0}", ex));
            throw ex;
        }

        return URL;
    }

    private int getDefaultURLExpiration()
    {
        int expirationDays = 0;
        try
        {
            // set the time span in days
            int.TryParse(configurationProvider.GetConfigurationValue("getDefaultURLExpiration() : Amazon_S3_ExportAds_ExpirationDaysOfURL"), out expirationDays);     // get from configuration util
        }
        catch
        {
            // in case of exception, set the min 14 days time space exiration
            expirationDays = defaultExpirationDays;
        }
        return expirationDays;
    }

    private void validateUpload(string fileName, Stream fileStream)
    {
        if (fileName == null || fileName.Equals(string.Empty) || fileStream.Length < 1)
        {
            throw new Exception("fileName : File name must not be an empty string.");
        }
        if (fileStream == null)
        {
            throw new Exception("fileStream : Input memory stream (file stream) must not be null.");
        }
    }

    #endregion

    #region Public methods

    public bool IsFileExists(string fileName, string awsS3BucketName)
    {
        bool fileExists = false;
        try
        {
            S3FileInfo fileInfo = new S3FileInfo(awsClientProvider.GetAmazonS3Client(), awsS3BucketName, fileName);
            fileExists = fileInfo.Exists;
        }
        catch (AmazonS3Exception Ex)
        {
            // log
            logger.WriteLog(String.Format("isFileExists() : Could not determine if file (key) exists in S3 Bucket.\r\n", Ex.Message));
            throw;
        }
        return fileExists;
    }

    public bool UploadObject(string fileName, Stream fileStream, string awsS3BucketName)
    {
        bool uploadResult = true;
        // Validate input parameters
        validateUpload(fileName, fileStream);

        if (awsClientProvider.GetAmazonS3Client() != null)
        {
            try
            {
                PutObjectRequest request = new PutObjectRequest
                {
                    BucketName = awsS3BucketName,
                    Key = fileName,
                    InputStream = fileStream
                };

                PutObjectResponse response = awsClientProvider.GetAmazonS3Client().PutObject(request);
                if (response != null)
                {
                    if (response.HttpStatusCode != System.Net.HttpStatusCode.OK)
                    {
                        var meta = response.ResponseMetadata.Metadata.Keys.
                            Select(k => k.ToString() + " : " + response.ResponseMetadata.Metadata[k]).
                            ToList().Aggregate((current, next) => current + "\r\n" + next);

                        // log error
                        logger.WriteLog(String.Format("Status Code: {0}\r\nETag : {1}\r\nResponse metadata : {1}",
                            (int)response.HttpStatusCode, response.ETag, meta));

                        // set the return value
                        uploadResult = false;
                    }
                }
            }
            catch (AmazonS3Exception ex)
            {
                uploadResult = false;

                if (ex.ErrorCode != null && (ex.ErrorCode.Equals("InvalidAccessKeyId") || ex.ErrorCode.Equals("InvalidSecurity")))
                {
                    // LOG
                    logger.WriteLog(String.Format("UploadObject() : invalied credentials"));
                    throw ex;
                }
                else
                {
                    // LOG
                    logger.WriteLog(String.Format("UploadObject() : Error occurred. Message:'{0}' when writing an object", ex.Message));
                    throw ex;
                }
            }
        }
        else
        {
            throw new Exception("UploadObject() : Could not start object upload because Amazon client is null.");
        }

        return uploadResult;
    }

    public bool UploadObject(string subFolderInBucket, string FileName, Stream fileStream, string awsS3BucketName)
    {
        return UploadObject(subFolderInBucket + @"/" + FileName, fileStream, awsS3BucketName);
    }

    public string GetURL(string fileName, string bucket)
    {
        string url = string.Empty;
        try
        {
            if (IsFileExists(fileName, bucket))
            {
                url = getFileUrl(fileName, getDefaultURLExpiration(), bucket);
            }
        }
        catch (Exception Ex)
        {
            // log
            logger.WriteLog(String.Format("getURL : Failed in isFileExists() method. \r\n{0}", Ex.Message));
        }
        return url;
    }

    #endregion
}
公共接口IConfigurationProvider
{
string GetConfigurationValue(string configurationKey);
}
公共接口ILogger
{
无效写日志(字符串消息);
}
公共接口IAWSClientProvider
{
AmazonS3Client GetAmazonS3Client();
}
公共接口IAWSBucketManager
{
字符串GetDefaultBucketName();
}
公共类AWSBucketManager:IAWSBucketManager
{
ILogger记录器;
IConfigurationProvider配置提供程序;
公用AWSBucketManager(ILogger记录器、IConfigurationProvider配置提供程序)
{
记录器=记录器;
configurationProvider=configurationProvider;
}
公共字符串GetDefaultBucketName()
{
string bucketName=string.Empty;
尝试
{
bucketName=configurationProvider.GetConfigurationValue(“Amazon_S3_ExportAds_bucketName”);
}
捕获(例外情况除外)
{
logger.WriteLog(String.Format(“getBucketName:无法从配置中获取存储桶名称。\r\n{0}”,ex));
}
返回bucketName;
}
}
公共类AWSClientProvider:IAWSClientProvider
{
IConfigurationProvider配置提供程序;
IAWSBucketManager awsBucketManager;
ILogger记录器;
私有字符串awsS3BucketName;
专用字典区域点;
公共AWSClientProvider(IConfigurationProvider配置提供程序、IAWSBucketManager BucketManager、ILogger记录器)
{
记录器=记录器;
configurationProvider=configurationProvider;
awsBucketManager=BucketManager;
}
私有区域点getAWSRegion()
{
RegionEndpoint RegionEndpoint=null;
//初始化端点字典
尝试
{
IEnumerable regions=RegionEndpoint.EnumerableAllRegions;
regionEndpoints=regions.ToDictionary(r=>r.SystemName,r=>r);
}
捕获(例外情况除外)
{
logger.WriteLog(String.Format(“getAWSRegion()-无法从AWS获取区域列表。\r\n{0}”,Ex));
投掷;
}
//获取配置值
尝试
{
string Config=configurationProvider.GetConfigurationValue(“亚马逊地区”);
if(String.IsNullOrEmpty(Config))
{
抛出新异常(“getAWSRegion():Amazon_S3_区域不能为null或空字符串”);
}
regionEndpoint=regionEndpoints[Config];
}
捕获(例外情况除外)
{
logger.WriteLog(String.Format(“getAWSRegion():无法从配置中获取区域设置。\r\n{0}”,Ex));
掷骰子;
}
返回区域点;
}
私有AWSCredentials getAWSCredentials()
{
字符串accessKey,secretKey;
基本要求;
尝试
{
accessKey=configurationProvider.GetConfigurationValue(“Amazon_S3_accessKey”);
secretKey=configurationProvider.GetConfigurationValue(“Amazon_S3_secretKey”);
}
捕获(例外情况除外)
{
logger.WriteLog(String.Format(“getAWSCredentials()-无法从配置中获取访问密钥和secrey密钥值。\r\n”,Ex.Message));
投掷;
}
尝试
{
awsCredentials=新的基本凭证(accessKey、secretKey);
}
捕获(例外情况除外)
{
logger.WriteLog(String.Format(“getAWSCredentials()-无法创建基本AWS凭据对象。\r\n{0}”,Ex.Message));
awsCredentials=null;
投掷;
}
返回awsCredentials;
}
公共AmazonS3Client GetAmazonS3Client()
{
AmazonS3Client客户端=null;
RegionEndpoint region=getAWSRegion();
AWSCredentials凭据=getAWSCredentials();
awsS3BucketName=awsBucketManager.GetDefaultBucketName();
如果(凭据!=null)
{
客户端=新的AmazonS3Client(凭据,地区);
}
返回客户;
}
}
公共类AWSS3动作
{
IConfigurationProvider configurationProvider;//正在获取配置
ILogger记录器;//解耦记录器
IAWSClientProvider awsClientProvider;
private const int defaultExpirationDays=14;
公共AWSS3操作(IConfigurationProvider配置提供程序、ILogger记录器、IAWSClientProvider客户端提供程序)
{
configurationProvider=configurationProvider;
记录器=记录器;
awsClientProvider=ClientProvider;
}
#区域私有方法
私有字符串getFileUrl(字符串文件名,int expirationDaysPeriod,字符串awsS3BucketName)
{
GetPreSignedUrlRequest请求=新建GetPreSignedUrlRequest();
字符串URL=“”;
DateTime dtBase=新的日期时间();
dtBase=DateTime.Now;
dtBase=dtBase.AddDays(expirationDaysPeriod);
request.BucketName=awsS3BucketName;
request.Key=文件名;
request.Expires=dtBase;
尝试
{
URL=awsClientProvider.GetAmazonS3Client().GetPreSignedURL(请求);
}
捕获(AmazonS3Exception ex)
{
//日志
logger.WriteLog(字符串)。