我想不出一个更好的方法来表达这一点,所以它可能就在那里,但我不知道它的用语.我有许多用于访问不同数据存储的类,它们遵循以下模式:
interface IUserData { User GetUser(uint id); User ByName(string username); } class UserData : IUserData { ... } class AuthorizedUserData : IUserData { IUserData _Data = new UserData(); public User GetUser(uint id) { AuthorizationHelper.Instance.Authorize(); return _Data.GetUser(id); } public User ByName(string name) { AuthorizationHelper.Instance.Authorize(); return _Data.ByName(name); } }
所以基本设置是:
>创建一个界面
>创建一个实际实现该接口的具体类
>为该类创建一个包装器,在调用具体类之前执行相同的工作
鉴于这些类实现了相同的接口,并且在包装类的每个方法的开头完成了完全相同的工作,这使我认为我可以自动化这个包装过程.
我知道在JavaScript和Python中创建这样的装饰器是可能的.
JavaScript中的示例:
function AuthorizedUserData() { ... } const userDataPrototype = Object.getPrototypeOf(new UserData()); Object.getownPropertyNames(userDataPrototype) .forEach(name => { const val = userDataPrototype[name]; if (typeof val !== 'function') { return; } AuthorizedUserData.prototype[name] = function(...args) { AuthorizationHelper.Authorize(); return this._Data[name](...args); }; });
在C#中这种自动实现是否可行?
解决方法
使用任何依赖注入(DI)框架.以下使用WindsorCastle.
使用nuget安装温莎城堡.
可以通过实现IInterceptor来创建拦截器
public class AuthorizedUserData : IInterceptor { public void Intercept(IInvocation invocation) { //Implement validation here } }
var container = new WindsorContainer(); container.Register(Castle.MicroKernel.Registration.Component.For<AuthorizedUserData>().LifestyleSingleton()); container.Register( Castle.MicroKernel.Registration .Classes .FromAssemblyInThisApplication() .BasedOn<IUserData>() .WithServiceAllInterfaces().Configure( x => x.Interceptors<AuthorizedUserData>()));
您的类和接口结构如下所示
public interface IUserData { User GetUser(uint id); User ByName(string username); } public class UserData : IUserData { public User GetUser(uint id) { throw new System.NotImplementedException(); } public User ByName(string username) { throw new System.NotImplementedException(); } } public class User { }
然后使用DI容器来解析您需要的实例.这里我们需要一个IUserData实例
var user = container.Resolve<IUserData>(); // Creates an instance of UserData user.ByName("userName"); //This call will first goto `Intercept` method and you can do validation.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。