我们在.net 3.5中。我想在一个程序集中保护某些方法(或类),以便只有另一个特定的程序集可以访问它。让我们称他们为消费者和提供者
我知道的一种方法是使用StrongNameIdentityPermissionAttribute
。问题是我们没有签署我们的集会。签署它将使所有地狱破裂。
另一种方式 - 使用Assembly.GetCallingAssembly().FullName
在代码中。并验证名称以匹配。有了这个,我必须在每个方法中编码,至少调用可重用的方法。确定。
当然还有InternalsVisibleTo
,但这不是我们想要的基础。
有没有其他方法可以在类级别或方法级别实现类似的东西,最好是基于属性的?我的意思是现有的框架功能。我可以开发我的自定义属性 - 毫无疑问
答案 0 :(得分:1)
一种可能性是将上面提到的GetCallingAssembly方法与Windsor Castle Proxy一起使用拦截器。您可以使用属性标记方法,将类保留为内部,并通过处理代理和拦截器的工厂公开构造(这需要您使内部对DynamicProxyGenAssembly2可见)。你的代码的消费者不需要做任何特殊的事情,它会在被调用时抛出。它是一个运行时错误,它不是很好但它能满足您的需求。
粗略的实现看起来像这样:
[TestFixture]
public class Foo
{
[Test]
public void Should_throw()
{
var nonProxyService = new Service();
nonProxyService.MethodWithSpecialPermissions().Should().BeTrue();
var interceptor = new PermissionInterceptor();
var generator = new ProxyGenerator();
var proxyService = (IService)generator.CreateClassProxy(
typeof(Service), new Type[] { typeof(IService) }, new IInterceptor[] { interceptor });
Assert.Throws<InvalidOperationException>(() => proxyService.MethodWithSpecialPermissions());
}
}
public interface IService
{
[SpecialPermissionAttribute]
bool MethodWithSpecialPermissions();
}
public class SpecialPermissionAttribute : Attribute
{
}
public class Service : IService
{
public bool MethodWithSpecialPermissions()
{
return true;
}
}
public class PermissionInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
if (invocation.Method.HasAttribute<SpecialPermissionAttribute>()
&& Assembly.GetCallingAssembly().FullName != "foo")
{
throw new InvalidOperationException();
}
invocation.Proceed();
}
}
我将属性放在接口上,因为向调用者传达它是一种奇怪的方法似乎是合理的,但它可能会通过一些工作转移到实现。