2011-01-19 36 views
0

我有一個名爲Repository的類,用於訪問(讀寫數據庫)。基於構造函數的方法的可用性

需要訪問數據庫的項目會創建一個Repository對象,並將連接字符串作爲構造函數參數傳遞給該特定項目的存儲庫。

我只有在某些連接字符串被傳遞時纔有可用的存儲庫中有幾個方法。如果傳遞了一些不同的連接字符串,我不希望它們可用。

有沒有什麼辦法可以做到這一點?

我從來沒有使用方法頭技術,可以幫助嗎?如果是的話,我該如何使用它?如果不是,請告訴我是否有其他方法可以實現我的目標。

問候。

+0

感謝大家的建議,我認爲這沒有「一個」答案... bu ti發現FactoryRepository /界面的建議更多的可採用,我想我會去...感謝所有一次再次... – user402186 2011-01-20 11:31:09

回答

0

排序這樣做的:

if (_connection == "XYZ") 
    throw new InvalidOperationException(); 

是否有可能,你可以重構你的方法來創建一個新類:

public class ConnectionInfo 
{ 
    public string ConnectionString { get; set; } 
    public bool IsLimitedAccess { get; set; } 
} 

然後,在每個存儲庫法不允許的,如果限制訪問,返回null或拋出異常或什麼?

+0

可能是這種變化,而不是`IsLimitedAccess`,有一個`IList `支持的命名操作。如果一組可用操作不同於連接到連接,單個標誌可能不夠靈活? – 2011-01-19 16:58:04

+0

是的,但是,如果不知道問題的全部細節是否需要去那個深度,它真的很難分辨出來...... – 2011-01-20 00:48:34

1

您可以使用factory method pattern來實現您的目標。
創建一個RepositoryFactory類,它接收連接字符串並根據字符串的內容返回不同的存儲庫。

public class RepositoryFactory { 

    public IRepository GetRepository(string connection) 
    { 
     if(SomeTestOnConnect(connection)) 
      return new SimpleRepository(connection); 
     else 
      return new FullRepository(connection); 

    } 
} 

當有人想要一個存儲庫時,他們會調用GetRepository方法。

0

如果事先你是否需要額外的方法知道了,你可以有一個基本版本不支持額外的方法,並派生類型的一樣。如果未提供所需的信息,派生類型的構造函數可能會引發異常。

使用工廠方法而不是構造函數將允許基於傳入的連接字符串構造基礎對象或花哨對象;如果你只有一個工廠方法,但是如果你想使用額外的方法,你必須對結果進行類型轉換。

最好的辦法可能是有一個工廠方法爲每個定義的類型,以保證它要麼返回一個對象是至少與請求的類型一樣好,甚至拋出如果不能例外。這種方法將允許將來的擴展,以防更多的派生類型可用。

0

如果要限制可用的方法,你可以使用這樣的模式。

使用工廠來得到這樣一個實例:

var repo = RepositoryFactory.Resovle<IFullRepository>("connection string"); 

這使得這項工作的代碼是在這裏

public class RepositoryFactory 
{ 
    public static T Resovle<T>(string connection) where T: IRepository 
    { 
     IRepository instance = new Repository(connection); 
     return (T)instance; 
    } 

    private class Repository : IFullRepository 
    { 
     private string _connection; 

     public Repository(string connection) 
     { 
      _connection = connection; 
     } 

     public object Get(int id) 
     { 
      // select 
     } 

     public void Save(object o) 
     { 
      // upate 
     } 

     public void Create(object o) 
     { 
      // create 
     } 

     public void CustomMethodOne() 
     { 
      // do something specialized 
     } 

     public void CustomMethodTwo() 
     { 
      // do something specialized 
     } 
    } 
} 

public interface IRepository 
{ 
    object Get(int id); 
    void Save(object o); 
    void Create(object o); 
} 

public interface IRepositoryProjectOne: IRepository 
{ 
    void CustomMethodOne(); 
} 

public interface IRepositoryProjectTwo: IRepository 
{ 
    void CustomMethodTwo(); 
} 

public interface IFullRepository: IRepositoryProjectOne, IRepositoryProjectTwo 
{ 

} 

的缺點是,你會得到接口的爆炸來控制什麼方法暴露。但是,可以在不同的接口之間進行轉換,但它避免了在方法未實現時不得不拋出異常。

0

似乎沒有要做到這一點,但是我覺得你的調用方法需要知道它是否被允許寫入到存儲庫作爲另一個海報曾表示方法的可用性的最佳方式是什麼,需要在編譯時而不是運行時知道。

解決方案是創建兩個接口,一個提供全部功能,另一個提供有限的功能。

public interface IRepository : IRead 
    { 
     void Write(object o); 
    } 

    public interface IRead 
    { 
     object Read(); 
    } 

Your Repository對象然後實現頂層接口。

public class Repository : IRepository 
    { 
     private readonly string _connectionString; 
     public Repository(string connectionString) 
     { 
      _connectionString = connectionString; 
     } 
     public object Read() 
     { 
      // Do stuff 
     } 

     public void Write(object o) 
     { 
      // Do stuff 
     } 
    } 

然後,您可以有確定的連接字符串需要一個只讀存儲庫與否,並公開2種不同的方法來返回給定類型接口的類(這意味着你必須知道在編譯時的類型) 。

public static class RepositoryFactory 
    { 
     public static bool ConnectionStringIsReadOnly(string connectionString) 
     { 
      return connectionString.Contains("user=hacker"); 
     } 

     public static IRead GetReadOnlyRepository(string connectionString) 
     { 
      return new Repository(connectionString); 
     } 

     public static IRepository GetRepository(string connectionString) 
     { 
      if (ConnectionStringIsReadOnly(connectionString)) throw new ArgumentException(@"Given connectionString is not allowed full repository access", "connectionString"); 
      return new Repository(connectionString); 
     } 
    } 

然後,您可以消耗這個如下,分離該點在那裏你嘗試這樣做,需要通過檢查你有一個版本IRepository或IREAD唯一的完全訪問權限的行爲。

public class Program 
    { 
     public void ConsumeRepository(string connectionString) 
     { 
      IRead reader = null; 
      IRepository repository = null; 
      if (RepositoryFactory.ConnectionStringIsReadOnly(connectionString)) 
       reader = RepositoryFactory.GetReadOnlyRepository(connectionString); 
      else 
      { 
       repository = RepositoryFactory.GetRepository(connectionString); 
       reader = repository; 
      } 

      object o = reader.Read(); 

      // do something with o 

      // if allowed then write o to repository 
      if (repository != null) 
      { 
       repository.Write(o); 
      } 
     } 
    } 
相關問題