Thứ Hai, 15 tháng 2, 2016

Resolved: configuration system failed to initialize

Obviously, the solution is to either repair or simply delete the user.config file, but we have to find it before we can do that. I won't get into repairing, since there's no simple way that I know of to do this. In most cases, deleting the user's application settings, while inconvenient, is not the end of the world, so long as the user is given fair warning that this is about to happen. You're free to take other measures, of course.

It turns out, the path to the user.config file was in the exception all along! But, it's sneakily hidden inside an InnerException, and maybe this is why it eluded me at first. So, allow me to present a block of code that will basically handle this occurrence in a universal manner. You should place this block somewhere near the beginning of your application startup, before any call to Settings is made:

try
        {
            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
        }
        catch (ConfigurationErrorsException ex)
        {
            string filename = string.Empty;
            if (!string.IsNullOrEmpty(ex.Filename))
            {
                filename = ex.Filename;
            }
            else
            {
                var innerEx = ex.InnerException as ConfigurationErrorsException;
                if (innerEx != null && !string.IsNullOrEmpty(innerEx.Filename))
                {
                    filename = innerEx.Filename;
                }                   
            }

            if (!string.IsNullOrEmpty(filename))
            {
                if (System.IO.File.Exists(filename))
                {
                    var fileInfo = new System.IO.FileInfo(filename);
                    var watcher
                         = new System.IO.FileSystemWatcher(fileInfo.Directory.FullName, fileInfo.Name);
                    System.IO.File.Delete(filename);
                    isReset = true;
                    if (System.IO.File.Exists(filename))
                    {
                        watcher.WaitForChanged(System.IO.WatcherChangeTypes.Deleted);
                    }
                }
            }
        }

ConfigurationErrorsException is the correct exception to throw in the situation you describe. An earlier version of the MSDN documentation for ConfigurationErrorsException makes more sense.
The earlier MSDN summary and remarks are:
  • The exception that is thrown when a configuration-system error has occurred.
  • The ConfigurationErrorsException exception is thrown when any error occurs while configuration information is being read or written.
Since CLR 2.0, the .NET Framework offers an extensive configuration module in System.Configuration. It differentiates between program and user settings:
TypeFileLocationOccurrenceUsage/Administration
Applicationapp.configProgram Folder1 per installationVisual Studio Project Properties: Settings
Useruser.configUser Profile Folder1 per userDerivation of ApplicationSettingsBase
The usage scenario determines which type of setting to choose:
Criterion/RequirementApplication SettingUser Setting
Setting is the same for all users (e.g., database connection)x
Setting can vary per user (e.g., theme)x
Temporary/local setting (e.g., location and size of a window)x
Storage of user input or selection (e.g., text alignment)x
Necessity to store settings fine grained (e.g., per plug-in)x

Control over the user settings is gained through inheriting from the class ApplicationSettingsBase. A single setting value can be defined via a property and a property attribute. The methods Reload(), Reset(), Save(), and Upgrade() determine the runtime behavior. The following illustration shows the data flow of the .NET user configuration:
User Settings Data Flow
The 'Default Value' is defined through the property attribute DefaultSettingValueAttribute. The value 'Init Value' is controlled by the .NET Framework. Access to the value of 'Session Value' occurs through the property which is marked with the UserScopedSettingAttribute, which in turn usesApplicationSettingsBase.Item.
The methods Reload() and Reset() support freshly loading all settings and setting them back to their 'Default Values, respectively.
When performing the first Save(), all user settings get stored in the XML file user.config. With every following program launch, the .NET Framework automatically loads them again (action Start). Where that configuration file will be located is influenced by several factors:
  • Profile Directory: The local or roaming profile directory (e.g., C:\Documents and Settings\MyName)
  • Company Name: The value of the AssemblyCompanyAttribute in AssemblyInfo.cs
  • App Name: The value of the AssemblyProductAttribute in AssemlyInfo.cs
  • Evidence Type and Evidence Hash: Information derived from the app domain evidence
  • Version: The value of the AssemblyVersionAttribute in AssemblyInfo.cs
If any of these factors change, the user settings will be stored (and looked for) in a different folder. The methodUpgrade() offers some support for migrating user settings from previous versions. Care should be taken, however, when changing either the company or the application name, as these changes will prevent future upgrades.

Read More »

Thứ Tư, 2 tháng 12, 2015

Factory method

Static Factory
Is a class with a Static Method to product various sub types of Product.
Static Factory
Simple Factory
Is a class that can produce various sub types of Product. (It is better than the Static Factory. When new types are added the base Product class does not need to be changed only the Simple Factory Class)
Simple Factoryt
Factory Method
Contains one method to produce one type of product related to its type. (It is better than a Simple Factory because the type is deferred to a sub-class.)
Factory Method
Abstract Factory
Produces a Family of Types that are related. It is noticeably different than a Factory Method as it has more than one method of types it produces. (This is complicated refer to next diagram for better real-life example).
Abstract Factory
Example From The .NET Framework
DbFactoriesProvider is a Simple Factory as it has no sub-types. The DbFactoryProvider is an abstract factory as it can create various related database objects such as connection and command objects.
Abstract Factory From .NET Framework
Read More »

Thứ Sáu, 27 tháng 11, 2015

Generic Repository in ASPNET5

In this post, I am explaining generic repository pattern using EF7. The Repository Pattern is a common construct to avoid duplication of data access logic throughout our application. The purpose of the repository is to hide the details of accessing the data. We can easily query the repository for data objects, without having to know how to provide things like a connection string. The Repository pattern adds a layer between the data and domain layers of an application. It also makes the data access parts of an application better testable.
Here is the initial version of repository interface.
1 public interface IEmployeeRepository
2 {
3     Task<Employee> Get(Guid? id);
4     Task Save(Employee employee);
5     Task Delete(Employee employee);
6     Task Update(Employee employee);
7     Task<IEnumerable<Employee>> FindAll();
8 }
It is specific to Employee class, respository contains CRUD operations. And here is the implementation ofEmployeeRepository class with DbContext.
 1 public class EmployeeRepository : IEmployeeRepository
 2 {
 3     private EmployeeContext _employeeContext;
 4     public EmployeeRepository()
 5     {
 6         _employeeContext = new EmployeeContext();
 7     }
 8     public async Task<Employee> Get(Guid? id)
 9     {
10         return await _employeeContext.Employees.FirstOrDefaultAsync(x => x.Id == id);
11     }
12     
13     public async Task Save(Employee employee)
14     {
15         _employeeContext.Employees.Add(employee);
16         await _employeeContext.SaveChangesAsync();
17     }
18     
19     public async Task Delete(Employee employee)
20     {
21         _employeeContext.Employees.Remove(employee);
22         await _employeeContext.SaveChangesAsync();
23     }
24     
25     public async Task Update(Employee employee)
26     {
27         _employeeContext.Employees.Update(employee);
28         await _employeeContext.SaveChangesAsync();
29     }
30     
31     public async Task<IEnumerable<Employee>> FindAll()
32     {
33         return await _employeeContext.Employees.ToListAsync();
34     }
35 }
And here is the Employee context object.
 1 public class EmployeeContext : DbContext
 2 {
 3     private static bool _created = false;
 4 
 5     public EmployeeContext()
 6     {
 7         if (!_created)
 8         {
 9             Database.EnsureCreated();
10             _created = true;
11         }
12     }
13     
14     public DbSet<Employee> Employees { get; set; }
15     protected override void OnConfiguring(EntityOptionsBuilder optionsBuilder)
16     {
17         optionsBuilder.UseInMemoryStore();
18     }
19 }
There are two problems with current EmployeeRepository implementation. First one it is using one model class, Employee, if you have multiple model classes, you need to duplicate lot of code. Second is it is not testable. The first problem you can fix by make it generic. And the second problem you can resolve by injecting the context object. Here is the generic repository interface.
1 public interface IGenericRepository<T> where T: class, IEntity, new()
2 {
3     Task<T> Get(Guid? id);
4     Task Save(T employee);
5     Task Delete(T employee);
6     Task Update(T employee);
7     Task<IEnumerable<T>> FindAll();
8 }
The IEntity interface contains only one property, Id.
1 public interface IEntity
2 {
3     Guid Id { get; set; }
4 }
And here is the implementation of GenericRepository class.
 1 public class GenericRepository<T> : IGenericRepository<T> where T: class, IEntity, new()
 2 {
 3     private DbContext _dbContext;
 4     public GenericRepository(DbContext dbContext)
 5     {
 6         _dbContext = dbContext;
 7     }
 8 
 9     public async Task Delete(T employee)
10     {
11         _dbContext.Set<T>().Remove(employee);
12         await _dbContext.SaveChangesAsync();
13     }
14 
15     public async Task<IEnumerable<T>> FindAll()
16     {
17         return await _dbContext.Set<T>().ToListAsync();
18     }
19 
20     public async Task<T> Get(Guid? id)
21     {
22         return await _dbContext.Set<T>().FirstOrDefaultAsync(x => x.Id == id);
23     }
24 
25     public async Task Save(T employee)
26     {
27         _dbContext.Set<T>().Add(employee);
28         await _dbContext.SaveChangesAsync();
29     }
30 
31     public async Task Update(T employee)
32     {
33         _dbContext.Set<T>().Update(employee);
34         await _dbContext.SaveChangesAsync();
35     }
36 }
In this implementation, one more problem exists, in the DbContext implementation, you need the reference ofEmployee model. You can make it DbContext also generic using Reflection.
 1 public class GenericDbContext : DbContext
 2 {
 3     private static bool _created = false;
 4     public GenericDbContext()
 5     {
 6         if (!_created)
 7         {
 8             Database.EnsureCreated();
 9             _created = true;
10         }
11     }
12     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
13     {
14         optionsBuilder.UseInMemoryDatabase(true);
15     }
16     protected override void OnModelCreating(ModelBuilder modelBuilder)
17     {
18         var types = Assembly.GetExecutingAssembly().GetTypes()
19             .Where(type => typeof(IEntity).IsAssignableFrom(type) && type.IsClass);
20         var method = typeof(ModelBuilder).GetMethods().First(m => m.Name == "Entity"
21             && m.IsGenericMethodDefinition
22             && m.GetParameters().Length == 0);
23         foreach (var type in types)
24         {
25             method = method.MakeGenericMethod(type);
26             method.Invoke(modelBuilder, null);
27         }
28 
29         base.OnModelCreating(modelBuilder);
30     }
31 }
In OnModelCreating method, all the types which implements IEntity interface are added to the DbContextusing Entity() method. This method is invoked dynamically using reflection. In ASP.NET 5, you can inject the repository and the context using inbuilt dependency injection feature.
1 public void ConfigureServices(IServiceCollection services)
2 {
3     services.AddMvc();
4     services.AddScoped<DbContext, GenericDbContext>();
5     services.AddScoped<IGenericRepository<Employee>, GenericRepository<Employee>>();
6 }
And here are the unit tests for create.
Happy programming! Smile | :)

Source: http://www.codeproject.com/Articles/1035618/Generic-Repository-in-ASPNET
Read More »

Thứ Sáu, 6 tháng 11, 2015

Khắc phục lỗi: system.web.webpages.html.htmlhelper' does not contain a definition for ViewBag...

Một ngày, mở project web MVC bỗng nhiên gặp lỗi: system.web.webpages.html.htmlhelper does not contain a definition for ViewBag...


Đây là cách khắc phục:
1. Tắt Visual Studio
2. Xóa hết mọi thứ trong thư mục bin và obj
3. Xóa temporary ASP.NET file trong thư mục: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files
4. Mở visual studio,  đổi sang version chính xác của System.Web.Mvc project, trong web.config ở Views. Vd:

<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
---> Version=5.0.0.0
5. Rebuild solution -> done
Read More »

Thứ Sáu, 30 tháng 10, 2015

SOLID là gì – Áp dụng các nguyên lý SOLID để trở thành lập trình viên code “cứng”

Trong quá trình học, hầu như các bạn sinh viên đều được học một số khái niệm OOP cơ bản như sau:
  • Abstraction (Tính trừu tượng)
  • Encapsulation (Tính bao đóng)
  • Inheritance (Tính kế thừa)
  • Polymophirsm (Tính đa hình)
Những khái niệm này đã được dạy khá rõ ràng, và hầu như những buổi phỏng vấn nào cũng có những câu hỏi liên quan đến khái niệm này. Vì 4 khái niệm này khá cơ bản, bạn nào chưa vũng có thể google để tìm hiểu thêm.
Những nguyên lý mình giới thiệu hôm nay là những nguyên lý thiết kế trong OOP. Đây là những nguyên lý được đúc kết bởi máu xương vô số developer, rút ra từ hàng ngàn dự án thành công và thất bại. Một project áp dụng những nguyên lý này sẽ có code dễ đọc, dễ test, rõ ràng hơn. Và việc quan trọng nhất là việc maintainace code sẽ dễ hơn rất nhiều (Ai có kinh nghiệm trong ngành IT đều biết thời gian code chỉ chiếm 20-40%, còn lại là thời gian để maintainance: thêm bớt chức năng và sửa lỗi). Nắm vững những nguyên lý này, đồng thời áp dụng chúng trong việc thiết kế + viết code sẽ giúp bạn tiến thêm 1 bước trên con đường thành senior nhé (1 ông senior bên FPT Software từng bảo mình thế).

Ok, 10 phút quảng cáo đã qua, bây giờ đến phần giới thiệu. SOLID tức là "cứng", áp dụng nhiều thì bạn sẽ code "cứng". Đùa thôi, nó là tập hợp 5 nguyên tắc sau đây:
  1. Single responsibility principle
  2. Open/closed principle
  3. Liskov substitution principle
  4. Interface segregation principle
  5. Dependency inversion principle
Trong nội dung bài viết này, mình chỉ giới thiệu tổng quát để các bạn có cái nhìn tổng quan về các nguyên lý này.

1. Single responsibility principle


Nguyên lý đầu tiên, tương ứng với chữ S trong SOLID. Nội dung nguyên lý:
Một class chỉ nên giữ 1 trách nhiệm duy nhất (Chỉ có thể sửa đổi
class với 1 lý do duy nhất)
Để hiểu nguyên lý này, ta hãy lấy ví dụ với 1 class vi phạm nguyên lý. Ta có 1 class như sau
public class ReportManager()
{
   public void ReadDataFromDB();
   public void ProcessData();
   public void PrintReport();
}
Class này giữ tới 3 trách nhiệm: Đọc dữ liệu từ DB, xử lý dữ liệu, in kết quả. Do đó, chỉ cần ta thay đổi DB, thay đổi cách xuất kết quả, … ta sẽ phải sửa đổi class này. Càng về sau class sẽ càng phình to ra. Theo đúng nguyên lý, ta phải tách class này ra làm 3 class riêng. Tuy số lượng class nhiều hơn những việc sửa chữa sẽ đơn giản hơn, class ngắn hơn nên cũng ít bug hơn.

2. Open/closed principle


Nguyên lý thứ hai, tương ứng với chữ O trong SOLID. Nội dung nguyên lý:
Có thể thoái mái mở rộng 1 class, nhưng không được sửa đổi
bên trong class đó (open for extension but closed for modification).
Theo nguyên lý này, mỗi khi ta muốn thêm chức năng,.. cho chương trình, chúng ta nên viết class mới mở rộng class cũ ( bằng cách kế thừa hoặc sở hữu class cũ) không nên sửa đổi class cũ.

3. Liskov Substitution Principle


Nguyên lý thứ ba, tương ứng với chữ L trong SOLID. Nội dung nguyên lý:
Trong một chương trình, các object của class con có thể
thay thế class cha mà không làm thay đổi
tính đúng đắn của chương trình
Hơi khó hiểu? Không sao, lúc mới đọc mình cũng vậy. Hãy tưởng tượng bạn có 1 class cha tên Vịt. Các class VịtBầu, VịtXiêm có thể kế thừa class này, chương trình chạy bình thường. Tuy nhiên nếu ta viết class VịtChạyPin,cần pin mới chạy được. Khi class này kế thừa class Vịt, vì không có pin không chạy được, sẽ gây lỗi. Đó là 1 trường hợp vi phạm nguyên lý này.

4. Interface Segregation Principle


Nguyên lý thứ tư, tương ứng với chữ I trong SOLID. Nội dung nguyên lý:
Thay vì dùng 1 interface lớn, ta nên tách thành nhiều
interface nhỏ, với nhiều mục đích cụ thể
Nguyên lý này khá dễ hiểu. Hãy tưởng tượng chúng ta có 1 interface lớn, khoảng 100 methods. Việc implements sẽ khá cực khổ, ngoài ra còn có thể dư thừa vì 1 class không cần dùng hết 100 method. Khi tách interface ra thành nhiều interface nhỏ, gồm các method liên quan tới nhau, việc implement + quản lý sẽ dễ hơn.

5. Dependency inversion principle


Nguyên lý cuối cùng, tương ứng với chữ D trong SOLID. Nội dung nguyên lý:
1. Các module cấp cao không nên phụ thuộc vào các modules cấp thấp.
   Cả 2 nên phụ thuộc vào abstraction.
2. Interface (abstraction) không nên phụ thuộc vào chi tiết, mà ngược lại. (Các class giao tiếp với nhau thông qua interface,
không phải thông qua implementation.)
Nguyên lý này khá lắt léo, mình sẽ lấy ví dụ thực tế. Chúng ta đều biết 2 loại đèn: đèn tròn và đèn huỳnh quang. Chúng cùng có đuôi tròn, do đó ta có thể thay thế đèn tròn bằng đèn huỳnh quanh cho nhau 1 cách dễ dàng.

Ở đây, interface chính là đuôi tròn, implementation là bóng đèn tròn và **bóng đèn huỳnh quang. **Ta có thể swap dễ dàng giữa 2 loại bóng vì ổ điện chỉ quan tâm tới interface (đuôi tròn), không quan tâm tới implementation.
Trong code cũng vậy, khi áp dụng Dependency Inverse, ta chỉ cần quan tâm tới interface. Để kết nối tới database, ta chỉ cần gọi hàm Get, Save … của Interface IDataAccess. Khi thay database, ta chỉ cần thay implementation của interface này.
Mình nói khá kĩ về nguyên lí này vì nó khá quan trọng. Về sau mình sẽ viết 1 bài riêng về Dependency Injection ( Dependency Injection chỉ là 1 trong những pattern để hiện thực Dependency Inversion, Dependency Injection != Dependency Inversion nhé các bạn), cùng với 1 số Dependency Injection Framework cơ bản.
Bài viết khá dài, xin có lời khen với các bạn đã kiên nhẫn đọc hết. Ở những bài viết sau mình sẽ giải thích rõ hơn về từng nguyên lý SOLID này, cùng với code mình họa + cách áp dụng nguyên lí vào quá trình code.

Read More »