2012-04-23 39 views
6

Tôi có một lớp học trong một ứng dụng web tôi đang làm việc trên đó giữ các cài đặt máy khách. Đối với một số nền tảng, tôi không sở hữu lớp này, và thay đổi nó không phải là một lựa chọn. Gần đây, chúng tôi đã thêm một số logic để lưu trữ các cài đặt trong cơ sở dữ liệu và tôi đã được giao nhiệm vụ tạo trang để chỉnh sửa chúng, đủ công bằng.C# - Khởi tạo lại lớp tĩnh?

Đây là vấn đề của tôi; các cài đặt được giữ trong một lớp tĩnh và bản thân chúng là các thuộc tính tĩnh, chỉ đọc. Ví dụ:

public static class Settings 
{ 
public static readonly setting1 = SettingmanagerClass.GetSetting("setting1"); 
public static readonly setting2 = SettingmanagerClass.GetSetting("setting2"); 
public static readonly setting3 = SettingmanagerClass.GetSetting("setting3"); 
} 

Bây giờ, ví dụ, thông qua trang tôi đã viết, chúng tôi thay đổi giá trị cho setting2 thành "Happy Variable"; nó tiết kiệm cho DB tốt, nhưng bây giờ tôi cần nó được phản ánh trong ứng dụng web như là giá trị mới. Vì nó là một thuộc tính chỉ đọc tĩnh của một lớp tĩnh, nó chỉ được gọi khi ứng dụng lần đầu tiên kết nối và không thể được đặt thủ công.

Chỉ cần nhắc lại, tôi không sở hữu lớp gốc, vì vậy "chỉ cần tạo thuộc tính có thể ghi" không phải là (hiện tại) là tùy chọn hợp lệ. Thông thường tôi sẽ nói chuyện này với ông chủ của tôi và anh ta sẽ gọi điện phán quyết và có thể cho phép tôi sửa đổi lớp khác, nhưng tôi không ở vị trí để thực hiện cuộc gọi đó và anh ấy đã ra khỏi văn phòng trong tuần.

Vì vậy, về cơ bản; có cách nào để khởi tạo lại một lớp tĩnh khi ứng dụng web đã bắt đầu chạy không? Tôi chỉ cần cho nó để tải lại tất cả các thuộc tính của nó như thể các ứng dụng đã được xây dựng lại và bắt đầu lên một lần nữa.

+0

Bạn có thể thay đổi nó bằng cách phản chiếu hoặc tái chế quy trình. [Đây là một chủ đề] (http://stackoverflow.com/questions/934930/can-i-change-a-private-readonly-field-in-c-sharp-using-reflection) về cách làm phản ánh: – zeal

+0

Chỉ cần một lưu ý: Bạn biết rằng tất cả các thiết lập (fe từ web.config) được lưu trữ không? –

+0

Có thể khởi động lại IIS của bạn không? [Bắt đầu hoặc dừng một hồ bơi ứng dụng (IIS 7)] (http://technet.microsoft.com/en-us/library/cc732742 (v = WS.10) .aspx) – Steve

Trả lời

2

Nếu mã trên đại diện cho tình huống bạn đang ở, bạn sẽ không thể khởi tạo lại mã trừ khi bạn làm điều gì đó đặc biệt bị tấn công với sự phản chiếu (điều này không được khuyến nghị).

Chỉnh sửa: Oh wait - Tôi không nhận ra đây là ứng dụng web. Bạn có thể lập trình bounce the application:

System.Web.HttpRuntime.UnloadAppDomain 
+0

Điều này có thể gây nguy hiểm cho dù người dùng khác có trong hệ thống và phiên bị mất do bị trả lại. – tsells

+0

@tells - tuyệt đối. – RQDQ

+0

Tôi thực sự chỉ thử nghiệm điều này đối với kịch bản mà tôi đã trình bày trong bài đăng gốc và nó đã hoạt động; không mất phiên nào cả, chỉ cần cài đặt lại. Hoàn hảo. Tôi đã thử nghiệm nó một vài lần để chắc chắn rằng tôi không chỉ vui mừng vì một thành công được cảm nhận, nhưng từ những gì tôi có thể thấy, đây là chiến thắng thuần túy, cảm ơn bạn! – ddietle

-2

Thay đổi giá trị của bạn để tính:

public static class Settings 
{ 
public static setting1 
{ 
    get { return SettingmanagerClass.GetSetting("setting1"); } 
} 
public static setting2 
{ 
    get { return SettingmanagerClass.GetSetting("setting2"); 
} 
public static setting3 
{ 
    get { return SettingmanagerClass.GetSetting("setting3"); 
} 
} 

Ngoài ra, điều này không thay đổi chữ ký của mã của bạn.

+3

OP nói rằng không thể chỉnh sửa mã trong lớp. –

+0

Ông nói, "không phải là (hiện tại) là một lựa chọn hợp lệ." Cách tôi đã mã hóa giữ cho các trường 'readonly' (nếu đây là một yêu cầu Customer hoặc Spec). Một cái gì đó đã thay đổi để cung cấp này. – jp2code

+2

Chỉ cần làm rõ, tôi không downvote. Dù bằng cách nào, ngữ nghĩa về các từ chính xác. Nếu OP * có thể * chỉnh sửa mã, cơ hội là rất tốt câu hỏi này sẽ không tồn tại. –

1

Các lựa chọn duy nhất nói đến cái tâm của tôi mà là đòi hỏi rất nhiều công việc:

  1. Tạo AppDomain khác
  2. tải lắp ráp trong lĩnh vực khác
  3. Sử dụng Remoting để có được những dữ liệu
  4. Nếu cài đặt đã thay đổi, hãy dỡ bỏ AppDomain và thực hiện lại các bước 1 đến 3
0

Hmm, bạn muốn tìm cách để hack lớp học ?thậm chí nếu nó tồn tại với sự phản ánh và một cái gì đó như thế, nó không phải là cách tốt để giải quyết

workaround nhanh này, tôi có thể đề nghị để tạo ra bạn sở hữu không chỉ đọc thuộc tính tĩnh, khởi tạo với các biến tĩnh và sử dụng chúng ở khắp mọi nơi

nhưng nó sẽ được tốt hơn để sử dụng bộ nhớ cache hoặc ứng dụng cửa hàng thay vì biến tĩnh

Hope this helps

+0

Sử dụng phiên không phải là một nơi thích hợp cho dữ liệu được đưa vào toàn bộ ứng dụng. Ngoài ra, OP nói rằng anh ta không sở hữu mã vi phạm. – RQDQ

+0

Đã chỉnh sửa, chắc chắn @RQDQ, Ứng dụng hoặc bộ nhớ cache sẽ tốt hơn –

4

Bạn có thể sử dụng phản ánh:

var prop = typeof(Settings).GetField("setting1", BindingFlags.Static | 
               BindingFlags.Public); 
prop.SetValue(null, "Bar"); 
string currentValue = Settings.setting1; //Bar 
.210
1

Tôi sẽ sử dụng phản ánh

var info = typeof(Settings) 
.GetField("Settings",BindingFlags.Static|BindingFlags.Public); 
info.SetValue(null, "setting4"); 
12
ConstructorInfo constructor = typeof(Settings).GetConstructor(BindingFlags.Static | BindingFlags.NonPublic,null, new Type[0], null); 
    constructor.Invoke(null, null); 
+0

Điều này thực sự hiệu quả. Thiên Chúa tôi ghét sự phản chiếu đôi khi lol –

+0

Cảm ơn. Tôi đã thử nghiệm với lớp OPs để chắc chắn hơn là đăng :) –

+0

Tôi mệt mỏi cái này, và tôi hoàn toàn làm việc, nhưng ứng dụng web vì một số lý do kỳ lạ tiếp tục tải các giá trị ban đầu trong các trang mặc dù trình gỡ lỗi hiển thị giá trị cập nhật. Rất kỳ lạ, và mặc dù tôi không dùng nó lần này, tôi sẽ giữ nó, nó rất tuyệt, ngay cả khi đó là lý do học tập (đối với tôi) ngay bây giờ. – ddietle

0

Cũ chủ đề tôi biết, nhưng có một điều tôi đã làm là tạo ra một Initialize phương pháp (public void tĩnh) mà bộ tất cả các biến (họ lại tất cả tĩnh công cộng). Trong phương thức đó, các cuộc gọi cơ sở dữ liệu được thực hiện và các biến của lớp được thiết lập. Sau đó, trong mã, bất cứ lúc nào bạn muốn làm mới các biến (tức là bất cứ lúc nào bạn gọi SaveChanges()), bạn có thể gọi Class.Initialize() và bạn đã hoàn tất.

Tôi sử dụng tính năng này để lưu vào bộ nhớ cache danh sách thông tin tra cứu chung có thể thay đổi và chúng tôi cần đồng bộ hóa thông tin đó khi cơ sở dữ liệu được cập nhật từ ứng dụng.

Các vấn đề liên quan