簡體   English   中英

具有接口的C#泛型約束以解耦API

[英]C# Generics Constraints with Interfaces to Decouple an API

在編寫數據訪問層時,我想將面向公眾的API與具體的數據庫實現分離。 例如,假設我要對我的后備存儲使用MongoDb或Cassandra。

因此,我想讓我的C#代碼通過工廠方法等利用IThingDao 。工廠將與實際實現相對應。

我有一些非常基本的界面和類示例來演示我希望實現的目標。 對我來說不幸的是,這段代碼產生了許多編譯時錯誤,這些錯誤表明類未實現接口的成員。

以下定義了我的數據對象:

public interface IBase
{
    Object Id { get; set; }
    DateTime CreatedDate { get; set; }    
}

public interface IBaseMongoDb : IBase
{
    // Common MongoDb related things used by all concrete implementations
}

public interface IBaseCassandra : IBase
{
    // Common Cassandra related things used by all concrete implementations
}

public interface IThing : IBase
{
    String Name { get; set; }
}

public abstract class AbstractBase
{
    public virtual Object Id { get; set; }
    public DateTime CreatedDate { get; set; }
}

public abstract class AbstractMongoDbBase : AbstractBase
{
    [BsonId]
    public override Object Id { get; set; }

    // Other specific MongoDb stuff
}

public abstract class AbstractCassandraBase : AbstractBase
{
    // Cassandra related stuff
}

public class ThingMongoDbImpl : AbstractMongoDbBase, IThing, IBaseMongoDb
{
    public String Name { get; set; }
}

public class ThingCassandraImpl : AbstractCassandraBase, IThing, IBaseCassandra
{
    public String Name { get; set; }
}

MongoDb和Cassandra數據對象有單獨的基本摘要,因為每種實現都有一個特定於另一種的共同特征(例如注釋等)。

這是數據訪問接口:

public interface IDao<T>
{
    T Save( T a_Value );
    void Update( T a_Value );
    void Delete( T a_Value );
    T Find( Object a_Key );
}

public interface IThingDao : IDao<IThing>
{
    IThing FindByName( String a_Name );
}

這是MongoDb和Cassandra的實現:

public abstract class AbstractMongoDbDao<T> where T : IBaseMongoDb, new()
{
    public T Save( T a_Value )
    {
        // Save
        return a_Value;
    }
    public void Update( T a_Value )
    {
        // Update
    }
    public void Delete( T a_Value )
    {
        // Delete
    }
    public T Find( Object a_Key )
    {
        return new T();
    }
}

public class ThingDaoMongoDbImpl : AbstractMongoDbDao<ThingMongoDbImpl>, IThingDao
{
    public IThing FindByName( String a_Name )
    {
        // Do the lookup and return value
        return new ThingMongoDbImpl();
    }
}


public abstract class AbstractCassandraDao<T> where T : IBaseCassandra, new()
{
    public T Save( T a_Value )
    {
        // Save
        return a_Value;
    }
    public void Update( T a_Value )
    {
        // Update
    }
    public void Delete( T a_Value )
    {
        // Delete
    }
    public T Find( Object a_Key )
    {
        return new T();
    }
}

public class ThingDaoCassandraImpl : AbstractCassandraDao<ThingCassandraImpl>, IThingDao
{
    public IThing FindByName( String a_Name )
    {
        // Do the lookup and return value
        return new ThingCassandraImpl();
    }
}

對於此代碼, ThingDaoMongoDbImplThingDaoCassandraImpl生成以下編譯時錯誤:

Error   1   'generics.decouple.ThingDaoMongoDbImpl' does not implement interface member 'generics.decouple.IDao<generics.decouple.IThing>.Find(object)'. 'generics.decouple.AbstractMongoDbDao<generics.decouple.ThingMongoDbImpl>.Find(object)' cannot implement 'generics.decouple.IDao<generics.decouple.IThing>.Find(object)' because it does not have the matching return type of 'generics.decouple.IThing'.
Error   2   'generics.decouple.ThingDaoMongoDbImpl' does not implement interface member 'generics.decouple.IDao<generics.decouple.IThing>.Delete(generics.decouple.IThing)' C:\Projects\EDC\modules\EXCHANGES\CAD2CAD.Net\Z\Generics.cs 95  18  Z
Error   3   'generics.decouple.ThingDaoMongoDbImpl' does not implement interface member 'generics.decouple.IDao<generics.decouple.IThing>.Update(generics.decouple.IThing)' C:\Projects\EDC\modules\EXCHANGES\CAD2CAD.Net\Z\Generics.cs 95  18  Z
Error   4   'generics.decouple.ThingDaoMongoDbImpl' does not implement interface member 'generics.decouple.IDao<generics.decouple.IThing>.Save(generics.decouple.IThing)'   C:\Projects\EDC\modules\EXCHANGES\CAD2CAD.Net\Z\Generics.cs 95  18  Z
Error   5   'generics.decouple.ThingDaoCassandraImpl' does not implement interface member 'generics.decouple.IDao<generics.decouple.IThing>.Find(object)'. 'generics.decouple.AbstractCassandraDao<generics.decouple.ThingCassandraImpl>.Find(object)' cannot implement 'generics.decouple.IDao<generics.decouple.IThing>.Find(object)' because it does not have the matching return type of 'generics.decouple.IThing'.
Error   6   'generics.decouple.ThingDaoCassandraImpl' does not implement interface member 'generics.decouple.IDao<generics.decouple.IThing>.Delete(generics.decouple.IThing)'   C:\Projects\EDC\modules\EXCHANGES\CAD2CAD.Net\Z\Generics.cs 126 18  Z
Error   7   'generics.decouple.ThingDaoCassandraImpl' does not implement interface member 'generics.decouple.IDao<generics.decouple.IThing>.Update(generics.decouple.IThing)'   C:\Projects\EDC\modules\EXCHANGES\CAD2CAD.Net\Z\Generics.cs 126 18  Z
Error   8   'generics.decouple.ThingDaoCassandraImpl' does not implement interface member 'generics.decouple.IDao<generics.decouple.IThing>.Save(generics.decouple.IThing)' C:\Projects\EDC\modules\EXCHANGES\CAD2CAD.Net\Z\Generics.cs 126 18  Z

關於如何使它工作的任何建議?

謝謝

public class ThingDaoMongoDbImpl : AbstractMongoDbDao<ThingMongoDbImpl>, IThingDao
{
    public IThing FindByName( String a_Name )
    {
        // Do the lookup and return value
        return new ThingMongoDbImpl();
    }

     T Save( T a_Value ) { //implement it
     }
     void Update( T a_Value ) { 
     //implement it here
     }
     void Delete( T a_Value ) { // implement it here}
     T Find( Object a_Key ) { //implement it}
}

因為沒有實現IThingDao接口的方法, IThingDao遇到了編譯時錯誤。 您的public interface IThingDao : IDao<IThing>從IDao擴展而來,因此您還必須實現IDao<IThing>的方法

更新

  public class ThingCassandraImpl : AbstractCassandraBase, IThing, IBaseCassandra, IThingDao
    {
        public String Name { get; set; }
        public IThing Save(IThing a_Value)
        {
            throw new NotImplementedException();
        }

        public void Update(IThing a_Value)
        {
            throw new NotImplementedException();
        }

        public void Delete(IThing a_Value)
        {
            throw new NotImplementedException();
        }

        public IThing Find(object a_Key)
        {
            throw new NotImplementedException();
        }

        public IThing FindByName(string a_Name)
        {
            throw new NotImplementedException();
        }
    }
    public abstract class AbstractCassandraDao<T> where T : IBaseCassandra,IThingDao, new() 
    {
        public T Save(T a_Value)
        {
            // Save
            return a_Value;
        }
        public void Update(T a_Value)
        {
            // Update
        }
        public void Delete(T a_Value)
        {
            // Delete
        }
        public T Find(Object a_Key)
        {
            return new T();
        }
    }

    public class ThingDaoCassandraImpl : AbstractCassandraDao<ThingCassandraImpl>
    {
        public IThing FindByName(String a_Name)
        {
            // Do the lookup and return value
            return new ThingCassandraImpl();
        }

        public IThing Save(IThing a_Value)
        {
            throw new NotImplementedException();
        }

        public void Update(IThing a_Value)
        {
            throw new NotImplementedException();
        }

        public void Delete(IThing a_Value)
        {
            throw new NotImplementedException();
        }

        public IThing Find(object a_Key)
        {
            throw new NotImplementedException();
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM